码迷,mamicode.com
首页 > 编程语言 > 详细

【KM算法】HDU2255-奔小康赚大钱

时间:2016-04-04 16:16:28      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:

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-奔小康赚大钱

标签:

原文地址:http://www.cnblogs.com/iiyiyi/p/5352199.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!