标签:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2426
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 #define inf 0x7fffffff 8 using namespace std; 9 const int maxn=500+10; 10 11 int n,m; 12 int lx[maxn],ly[maxn],visx[maxn],visy[maxn]; 13 int link[maxn],slack[maxn],w[maxn][maxn]; 14 15 int dfs(int x) 16 { 17 visx[x]=1; 18 for (int y=1 ;y<=m ;y++) if (w[x][y]!=-1) 19 { 20 if (visy[y]) continue; 21 int t=lx[x]+ly[y]-w[x][y]; 22 if (t==0) 23 { 24 visy[y]=1; 25 if (link[y]==-1 || dfs(link[y])) 26 { 27 link[y]=x; 28 return 1; 29 } 30 } 31 else if (slack[y]>t) slack[y]=t; 32 } 33 return 0; 34 } 35 36 int KM() 37 { 38 memset(link,-1,sizeof(link)); 39 memset(ly,0,sizeof(ly)); 40 for (int x=1 ;x<=n ;x++) 41 { 42 lx[x]=-inf; 43 for (int y=1 ;y<=m ;y++) 44 lx[x]=max(lx[x],w[x][y]); 45 } 46 for (int x=1 ;x<=n ;x++) 47 { 48 for (int i=1 ;i<=m ;i++) slack[i]=inf; 49 int flag=0; 50 for (int i=1 ;i<=m ;i++) if (w[x][i]!=-1) flag=1; 51 while (flag) 52 { 53 memset(visx,0,sizeof(visx)); 54 memset(visy,0,sizeof(visy)); 55 if (dfs(x)) break; 56 int d=inf; 57 for (int i=1 ;i<=m ;i++) 58 if (!visy[i] && d>slack[i]) d=slack[i]; 59 for (int i=1 ;i<=n ;i++) 60 if (visx[i]) lx[i] -= d; 61 for (int i=1 ;i<=m ;i++) 62 { 63 if (visy[i]) ly[i] += d; 64 else slack[i] -= d; 65 } 66 } 67 } 68 int ans=0; 69 int vis[maxn]; 70 memset(vis,0,sizeof(vis)); 71 for (int i=1 ;i<=m ;i++) 72 { 73 if (link[i]!=-1) 74 { 75 ans += w[link[i] ][i]; 76 vis[link[i] ]=1; 77 } 78 } 79 int i=1; 80 for (i=1 ;i<=n ;i++) 81 if (vis[i]==0) return -1; 82 return ans; 83 } 84 85 int main() 86 { 87 int e; 88 int ncase=1; 89 while (scanf("%d%d%d",&n,&m,&e)!=EOF) 90 { 91 memset(w,-1,sizeof(w)); 92 int a,b,c; 93 for (int i=0 ;i<e ;i++) 94 { 95 scanf("%d%d%d",&a,&b,&c); 96 a++ ;b++ ; 97 if (c>=0) w[a][b]=c; 98 } 99 printf("Case %d: %d\n",ncase++,KM()); 100 } 101 return 0; 102 }
hdu 2426 Interesting Housing Problem 最大权匹配KM算法
标签:
原文地址:http://www.cnblogs.com/huangxf/p/4339563.html