Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 5964 | Accepted: 2502 |
Description
Input
Output
Sample Input
2 2 08:00 10 11 9 16 08:07 9 16 10 11 2 08:00 10 11 9 16 08:06 9 16 10 11
Sample Output
1 2
poj2060:每个任务有起点和终点,当完成自身任务,又从终点到下一个地点的起点,若曼哈顿距离之和小于该车的时间说明这辆车可以完成这两个任务,于是就连边。本题就是最小路径覆盖问题,化归为|V|-二分图的最大匹配。
代码:
#include<cstdio> #include<iostream> #include<cstring> #include<cmath> #define Maxn 510 using namespace std; struct point{ int m,sx,sy,ex,ey; }p[Maxn]; int dis(int x1,int y1,int x2,int y2){ return abs(x1-x2)+abs(y1-y2); } int adj[Maxn][Maxn]; int match[Maxn]; int vis[Maxn]; int x,y; int deep; bool dfs(int u){ for(int v=1;v<=y;v++){ if(adj[u][v]&&vis[v]!=deep){ vis[v]=deep; if(match[v]==-1||dfs(match[v])){ match[v]=u; return true; } } } return false; } int hungary(){ memset(match,-1,sizeof match); memset(vis,-1,sizeof vis); int ans=0; for(int i=1;i<=x;i++){ deep=i; if(dfs(i)) ans++; } return ans; } int main() { int t,a,b; cin>>t; while(t--){ cin>>x; y=x; for(int i=1;i<=x;i++){ scanf("%d:%d%d%d%d%d",&a,&b,&p[i].sx,&p[i].sy,&p[i].ex,&p[i].ey); p[i].m=a*60+b; } memset(adj,0,sizeof adj); for(int i=1;i<=x;i++) for(int j=i+1;j<=x;j++){ int d1=dis(p[i].sx,p[i].sy,p[i].ex,p[i].ey), d2=dis(p[i].ex,p[i].ey,p[j].sx,p[j].sy); if(d1+d2<p[j].m-p[i].m) adj[i][j]=1; } printf("%d\n",x-hungary()); } return 0; }
poj2594可重点的最小路径覆盖,这个只要用floyd预处理两点是否可达,然后求普通的最小路径覆盖即可。
Time Limit: 6000MS | Memory Limit: 65536K | |
Total Submissions: 6991 | Accepted: 2843 |
Description
Input
Output
Sample Input
1 0 2 1 1 2 2 0 0 0
Sample Output
1 1 2
代码:
#include<cstdio> #include<iostream> #include<cstring> #define Maxn 510 using namespace std; int adj[Maxn][Maxn]; int match[Maxn]; int vis[Maxn]; int x,y; int deep; bool dfs(int u){ for(int v=1;v<=y;v++){ if(adj[u][v]&&vis[v]!=deep){ vis[v]=deep; if(match[v]==-1||dfs(match[v])){ match[v]=u; return true; } } } return false; } int hungary(){ memset(match,-1,sizeof match); memset(vis,-1,sizeof vis); int ans=0; for(int i=1;i<=x;i++){ deep=i; if(dfs(i)) ans++; } return ans; } int main() { int n,m,a,b; while(cin>>n>>m,n){ memset(adj,0,sizeof adj); for(int i=0;i<m;i++){ cin>>a>>b; adj[a][b]=1; } for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) adj[i][j]=adj[i][j]|adj[i][k]&adj[k][j]; x=y=n; printf("%d\n",n-hungary()); } return 0; }
poj1548最小路径覆盖,对于满足p[i].x<=p[j].x&&p[i].y<=p[j].y这个条件的i,j建一条i指向j的边。
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 3970 | Accepted: 1810 |
Description
Input
Output
Sample Input
1 2 1 4 2 4 2 6 4 4 4 7 6 6 0 0 1 1 2 2 4 4 0 0 -1 -1
Sample Output
2 1
代码:
#include<cstdio> #include<iostream> #include<cstring> #define Maxn 25*25 using namespace std; struct point{ int x,y; point(){} point(int xx,int yy):x(xx),y(yy){} bool operator<(const point &a)const{ return x<=a.x&&y<=a.y; } }p[Maxn]; int adj[Maxn][Maxn]; int match[Maxn]; int vis[Maxn]; int x,y; int deep; bool dfs(int u){ for(int v=1;v<=y;v++){ if(adj[u][v]&&vis[v]!=deep){ vis[v]=deep; if(match[v]==-1||dfs(match[v])){ match[v]=u; return true; } } } return false; } int hungary(){ memset(match,-1,sizeof match); memset(vis,-1,sizeof vis); int ans=0; for(int i=1;i<=x;i++){ deep=i; if(dfs(i)) ans++; } return ans; } int main() { int a,b; while(cin>>a>>b,a!=-1){ if(!a) break; int tot=0; p[++tot]=point(a,b); while(cin>>a>>b,a){ p[++tot]=point(a,b); } memset(adj,0,sizeof adj); for(int i=1;i<=tot;i++) for(int j=i+1;j<=tot;j++) if(p[i]<p[j]) adj[i][j]=1; x=y=tot; printf("%d\n",tot-hungary()); } return 0; }
poj3216最小路径覆盖,以每个任务作为节点建图,首先用floyd预处理各点之间的最短路mat,然后若满足p[i].d+p[i].t+mat[i][j]<=p[j].d这个条件,说明完成i任务后可赶赴j任务,于是将i+1到j+1连一条边,+1是为了保证几点从1开始。
Time Limit: 1000MS | Memory Limit: 131072K | |
Total Submissions: 6446 | Accepted: 1730 |
Description
Lily runs a repairing company that services the Q blocks in the city. One day the company receives M repair tasks, the ith of which occurs in block pi, has a deadline ti on any repairman’s arrival, which is also its starting time, and takes a single repairman di time to finish. Repairmen work alone on all tasks and must finish one task before moving on to another. With a map of the city in hand, Lily want to know the minimum number of repairmen that have to be assign to this day’s tasks.
Input
The input contains multiple test cases. Each test case begins with a line containing Q and M (0 < Q ≤ 20, 0 < M ≤ 200). Then follow Q lines each with Q integers, which represent a Q × Q matrix Δ = {δij}, where δij means a bidirectional road connects the ith and the jth blocks and requires δij time to go from one end to another. If δij = −1, such a road does not exist. The matrix is symmetric and all its diagonal elements are zeroes. Right below the matrix are M lines describing the repairing tasks. The ith of these lines contains pi, ti and di. Two zeroes on a separate line come after the last test case.
Output
For each test case output one line containing the minimum number of repairmen that have to be assigned.
Sample Input
1 2 0 1 1 10 1 5 10 0 0
Sample Output
2
代码:
#include<cstdio> #include<iostream> #include<cstring> #define Maxn 210 using namespace std; struct point{ int id,d,t; }p[Maxn]; int adj[Maxn][Maxn]; int match[Maxn]; int vis[Maxn]; int x,y; int deep; bool dfs(int u){ for(int v=1;v<=y;v++){ if(adj[u][v]&&vis[v]!=deep){ vis[v]=deep; if(match[v]==-1||dfs(match[v])){ match[v]=u; return true; } } } return false; } int hungary(){ memset(match,-1,sizeof match); memset(vis,-1,sizeof vis); int ans=0; for(int i=1;i<=x;i++){ deep=i; if(dfs(i)) ans++; } return ans; } const int inf=0x3f3f3f3f; int mat[Maxn][Maxn]; int main() { int n,m; while(cin>>n>>m,n){ for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ cin>>mat[i][j]; if(mat[i][j]==-1) mat[i][j]=inf; } for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) mat[i][j]=min(mat[i][j],mat[i][k]+mat[k][j]); for(int i=0;i<m;i++){ cin>>p[i].id>>p[i].d>>p[i].t; } memset(adj,0,sizeof adj); for(int i=0;i<m;i++) for(int j=0;j<m;j++) if(i!=j&&p[i].d+p[i].t+mat[p[i].id][p[j].id]<=p[j].d){ adj[i+1][j+1]=1; } x=y=m; printf("%d\n",m-hungary()); } return 0; }