HDU 2255 奔小康赚大钱(最佳二分图匹配)
2017-01-02 14:06
393 查看
#include<iostream> using namespace std; const int maxn=300+5; int w[maxn][maxn],n; int lx[maxn],ly[maxn]; int Left[maxn]; bool s[maxn],t[maxn]; bool match(int i) { s[i]=true; for(int j=1;j<=n;j++) if(lx[i]+ly[j]==w[i][j]&&!t[j]){ t[j]=true; if(!Left[j]||match(Left[j])){ Left[j]=i; return true; } } return false; } void update() { int a=(1<<30); for(int i=1;i<=n;i++) if(s[i]) for(int j=1;j<=n;j++) if(!t[j]) a=min(a,lx[i]+ly[j]-w[i][j]); for(int i=1;i<=n;i++){ if(s[i]) lx[i]-=a; if(t[i]) ly[i]+=a; } } void KM() { for(int i=1;i<=n;i++){ Left[i]=lx[i]=ly[i]=0; for(int j=1;j<=n;j++) lx[i]=max(lx[i],w[i][j]); } for(int i=1;i<=n;i++){ for(;;) { for(int j=1;j<=n;j++) s[j]=t[j]=0; if(match(i)) break;else update(); } } } int main() { while(~scanf("%d",&n)) { for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&w[i][j]); KM(); int ans=0; for(int i=1;i<=n;i++) ans+=w[Left[i]][i]; printf("%d\n",ans); } return 0; }
相关文章推荐
- 奔小康赚大钱 - HDU 2255 - 二分图匹配
- HDU 2255 奔小康赚大钱 (KM最佳完美匹配)
- HDU-#2255 奔小康赚大钱(二分图最佳完美匹配+KM)
- 【KM模板】HDU 2255 奔小康赚大钱
- HDU 2255 奔小康赚大钱
- HDU 2255 奔小康赚大钱 (KM算法+二分图最大权匹配)
- HDU 2255 奔小康赚大钱(KM算法)
- hdu 2255 奔小康赚大钱(二分图的最优匹配)
- HDU 2255 奔小康赚大钱 KM裸题
- hdu 2255 奔小康赚大钱【Kuhn_Munkras】
- HDU-2255 奔小康赚大钱 (KM模板)
- HDU 2255 ——奔小康赚大钱——————【KM算法裸题】
- HDU 2255 奔小康赚大钱(KM完美匹配)
- HDU-2255 奔小康赚大钱 最大权值匹配
- 奔小康赚大钱 HDU - 2255
- HDU 2255 - 奔小康赚大钱
- hdu_2255 奔小康赚大钱(KM算法)
- 奔小康赚大钱 hdu 2255
- 【HDU 2255】【KM算法模板题+KM算法详解】 奔小康赚大钱
- [ACM] HDU 2255 奔小康赚大钱 (二分图最大权匹配,KM算法)