题目链接:http://poj.org/problem?id=2060
当时一看的题目,就想到用贪心搞,于是马上敲之,后来发现还是不行啊,比如4->2->3 1->2->3 1->5,有这样几条路径,然后贪心可能会出现这种结果:4->2->3 1 5,那么答案就是3了,但是这里显然答案是2啊!
然后就建图了,猛然发现是最小路径覆盖:把每条路径看做点集合,然后taxi能合法到达的建立边。题目要用最少的车,那么就是用最少的路径把图中的所用点覆盖了,即n-最大匹配数即可。
1 //STATUS:G++_AC_141MS_1708KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #include<string> 8 #include<algorithm> 9 #include<vector> 10 #include<queue> 11 #include<stack> 12 #include<map> 13 using namespace std; 14 #define LL long long 15 #define Max(a,b) ((a)>(b)?(a):(b)) 16 #define Min(a,b) ((a)<(b)?(a):(b)) 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define lson l,mid,rt<<1 19 #define rson mid+1,r,rt<<1|1 20 const int MAX=510,INF=200000000; 21 22 int vis[MAX],y[MAX],g[MAX][MAX]; 23 int T,n; 24 struct Node{ 25 int t,x1,y1,x2,y2; 26 }nod[MAX]; 27 28 int dfs(int u) 29 { 30 int v; 31 for(v=0;v<n;v++){ 32 if(g[u][v] && !vis[v]){ 33 vis[v]=1; 34 if(y[v]==-1 || dfs(y[v])){ 35 y[v]=u; 36 return 1; 37 } 38 } 39 } 40 return 0; 41 } 42 43 int main() 44 { 45 // freopen("in.txt","r",stdin); 46 int i,j,ans; 47 char s[8]; 48 scanf("%d",&T); 49 while(T--) 50 { 51 ans=0; 52 mem(g,0); 53 mem(y,-1); 54 scanf("%d",&n); 55 for(i=0;i<n;i++){ 56 scanf("%s%d%d%d%d",s,&nod[i].x1,&nod[i].y1,&nod[i].x2,&nod[i].y2); 57 nod[i].t=((s[0]-'0')*10+(s[1]-'0'))*60+((s[3]-'0')*10+(s[4]-'0')); 58 } 59 60 for(i=0;i<n;i++){ 61 for(j=0;j<n;j++){ 62 if(i!=j && nod[i].t+abs(nod[i].x1-nod[i].x2)+abs(nod[i].y1-nod[i].y2) 63 +abs(nod[i].x2-nod[j].x1)+abs(nod[i].y2-nod[j].y1)+1<=nod[j].t) 64 g[i][j]=1; 65 } 66 } 67 68 for(i=0;i<n;i++){ 69 mem(vis,0); 70 if(dfs(i))ans++; 71 } 72 printf("%d\n",n-ans); 73 } 74 return 0; 75 }