HDU 2063 过山车(匈牙利算法求二分图最大匹配)
http://acm.hdu.edu.cn/showproblem.php?pid=2063
因为要补某一道cf题特意来学一下。。。
匈牙利算法关键在于在能“反悔”的时候尽量“反悔”进行新的匹配以获得更多的匹配数。具体建议看代码很好看懂~
1 #define bug(x) cout<<#x<<" is "<<x<<endl 2 #define IO std::ios::sync_with_stdio(0) 3 #include <bits/stdc++.h> 4 #define pa pair<int,int> 5 #define iter ::iterator 6 using namespace std; 7 #define ll long long 8 #define mk make_pair 9 #define pb push_back 10 #define se second 11 #define fi first 12 #define ls o<<1 13 #define rs o<<1|1 14 ll mod=998244353; 15 const int N=1e3+5; 16 int q,n,m; 17 int g[N][N]; 18 int vis[N]; 19 int a[N]; 20 int find(int x){ 21 for(int i=1;i<=m;i++){ 22 if(g[x][i]&&!vis[i]){ 23 vis[i]=1; 24 if(!a[i]||find(a[i])){ 25 a[i]=x; 26 return 1; 27 } 28 } 29 } 30 return 0; 31 } 32 int main(){ 33 while(~scanf("%d",&q)&&q){ 34 scanf("%d%d",&n,&m); 35 memset(g,0,sizeof(g)); 36 memset(a,0,sizeof(a)); 37 for(int i=1;i<=q;i++){ 38 int x,y; 39 scanf("%d%d",&x,&y); 40 g[x][y]=1; 41 } 42 int ans=0; 43 for(int i=1;i<=n;i++){ 44 memset(vis,0,sizeof(vis)); 45 if(find(i))ans++; 46 } 47 printf("%d\n",ans); 48 } 49 }