KM算法HDU2255-奔小康赚大钱
Posted Yiyi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了KM算法HDU2255-奔小康赚大钱相关的知识,希望对你有一定的参考价值。
KM算法的裸体。O(n^4)的模板,实际上在增广路径的时候依然有冗余,可以用bfs优化到O(n^3)。
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <cstring> 5 #include <cstdlib> 6 #include <algorithm> 7 using namespace std; 8 const int MAXN=400+5; 9 const int INF=0x7fffffff; 10 int n,m; 11 int w[MAXN][MAXN]; 12 int x[MAXN],y[MAXN]; 13 int visx[MAXN],visy[MAXN],slack[MAXN]; 14 int lk[MAXN]; 15 16 int dfs(int u) 17 { 18 visx[u]=1; 19 for (int i=1;i<=n;i++) 20 { 21 int wt=x[u]+y[i]-w[u][i]; 22 if (!visy[i] && wt==0) 23 { 24 visy[i]=1; 25 if (lk[i]==-1 || dfs(lk[i])) 26 { 27 lk[i]=u; 28 return 1; 29 } 30 } 31 else if (slack[i]>wt) slack[i]=wt; 32 } 33 return 0; 34 } 35 36 int KM() 37 { 38 memset(lk,-1,sizeof(lk)); 39 for (int i=1;i<=n;i++) 40 { 41 y[i]=0; 42 x[i]=-INF; 43 for (int j=1;j<=n;j++) x[i]=max(x[i],w[i][j]); 44 } 45 for (int i=1;i<=n;i++) 46 { 47 memset(visx,0,sizeof(visx)); 48 memset(visy,0,sizeof(visy)); 49 memset(slack,127,sizeof(slack)); 50 while (!dfs(i)) 51 { 52 int delta=INF; 53 for (int j=1;j<=n;j++) 54 if (!visy[j] && slack[j]<delta) delta=slack[j]; 55 for (int j=1;j<=n;j++) 56 { 57 if (visx[j]) 58 { 59 x[j]-=delta; 60 visx[j]=0; 61 } 62 if (visy[j]) 63 { 64 y[j]+=delta; 65 visy[j]=0; 66 } 67 } 68 } 69 } 70 int ret=0; 71 for (int i=1;i<=n;i++) ret+=x[i]+y[i]; 72 return ret; 73 } 74 75 void init() 76 { 77 memset(w,0,sizeof(w)); 78 for (int i=1;i<=n;i++) 79 { 80 for (int j=1;j<=n;j++) 81 scanf("%d",&w[i][j]); 82 } 83 } 84 85 int main() 86 { 87 while (~scanf("%d",&n)) 88 { 89 init(); 90 printf("%d\n",KM()); 91 } 92 return 0; 93 }
以上是关于KM算法HDU2255-奔小康赚大钱的主要内容,如果未能解决你的问题,请参考以下文章