hdu2389+二分匹配(Hopcroft-Karp算法)
题意很简单,显然是对客人与伞做匹配,求最大匹配数。
一开始用了匈牙利,果断TLE。。。
好吧,原来二分匹配还有这个奇葩算法。。然而敲完还是不明白这个算法啥意思。。。
附两个算法的时间复杂度:
匈牙利:O(VE)
H-K :O(V^0.5 E)
1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #include<queue> 5 using namespace std; 6 int nx,ny,mx[3300],my[3300],dx[3300],dy[3300],vis[3300]; 7 vector<int> v[3300]; 8 struct node1 9 { 10 int x,y,sp; 11 }per[3300]; 12 struct node2 13 { 14 int x,y; 15 }umb[3300]; 16 bool dfs(int u) 17 { 18 int v2,i; 19 for(i=0;i<v[u].size();i++) 20 { 21 v2=v[u][i]; 22 if(!vis[v2]&&dy[v2]==dx[u]+1) 23 { 24 vis[v2]=1; 25 if(my[v2]==-1||dfs(my[v2])) 26 { 27 my[v2]=u; 28 mx[u]=v2; 29 return true; 30 } 31 } 32 } 33 return false; 34 } 35 int hkmatch() 36 { 37 int ret=0; 38 memset(mx,-1,sizeof(mx)); 39 memset(my,-1,sizeof(my)); 40 while(true) 41 { 42 int i; 43 bool flag=false; 44 queue<int> q; 45 memset(dx,0,sizeof(dx)); 46 memset(dy,0,sizeof(dy)); 47 for(i=1;i<=nx;i++) 48 { 49 if(mx[i]==-1) 50 { 51 q.push(i); 52 } 53 } 54 while(!q.empty()) 55 { 56 int z=q.front(); 57 q.pop(); 58 for(i=0;i<v[z].size();i++) 59 { 60 int vv=v[z][i]; 61 if(!dy[vv]) 62 { 63 dy[vv]=dx[z]+1; 64 if(my[vv]==-1) flag=true; 65 else 66 { 67 dx[my[vv]]=dy[vv]+1; 68 q.push(my[vv]); 69 } 70 } 71 } 72 } 73 if(flag==false) break; 74 memset(vis,0,sizeof(vis)); 75 for(i=1;i<=nx;i++) 76 { 77 if(mx[i]==-1&&dfs(i)) 78 ret++; 79 } 80 } 81 return ret; 82 } 83 84 int main() 85 { 86 int cas,i,j,numcas=0; 87 scanf("%d",&cas); 88 while(cas--) 89 { 90 int t; 91 scanf("%d",&t); 92 scanf("%d",&nx); 93 for(i=1;i<=nx;i++) 94 v[i].clear(); 95 for(i=1;i<=nx;i++) 96 scanf("%d%d%d",&per[i].x,&per[i].y,&per[i].sp); 97 scanf("%d",&ny); 98 for(i=1;i<=ny;i++) 99 scanf("%d%d",&umb[i].x,&umb[i].y); 100 for(i=1;i<=nx;i++) 101 { 102 for(j=1;j<=ny;j++) 103 { 104 if(per[i].sp*t*per[i].sp*t>=(per[i].x-umb[j].x)*(per[i].x-umb[j].x)+(per[i].y-umb[j].y)*(per[i].y-umb[j].y)) 105 v[i].push_back(j); 106 } 107 } 108 printf("Scenario #%d:\n",++numcas); 109 printf("%d\n\n",hkmatch()); 110 } 111 return 0; 112 }