HDU 2255 奔小康赚大钱(KM算法)

题目链接

最大的二分图带权匹配,KM算法模版题,抄的别人的。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <string>
 4 #include <cstdio>
 5 using namespace std;
 6 #define N 301
 7 #define INF 0x7fffffff
 8 int mat[N][N];
 9 int match[N];
10 int inx[N],iny[N];
11 int lx[N],ly[N];
12 int n;
13 int dfs(int u)
14 {
15     int i;
16     inx[u] = 1;
17     for(i = 1;i <= n;i ++)
18     {
19         if(!iny[i]&&lx[u] + ly[i] == mat[u][i])
20         {
21             iny[i] = 1;
22             if(match[i] == -1||dfs(match[i]))
23             {
24                 match[i] = u;
25                 return 1;
26             }
27         }
28     }
29     return 0;
30 
31 }
32 void KM()
33 {
34     int i,j,k,temp;
35     memset(lx,0,sizeof(lx));
36     memset(ly,0,sizeof(ly));
37     for(i = 1;i <= n;i ++)
38     {
39         for(j = 1;j <= n;j ++)
40         lx[i] = max(mat[i][j],lx[i]);
41     }
42     for(i = 1;i <= n;i ++)
43     {
44         for(;;)
45         {
46             memset(inx,0,sizeof(inx));
47             memset(iny,0,sizeof(iny));
48             if(dfs(i))
49             break;
50             else
51             {
52                 temp = INF;
53                 for(j = 1;j <= n;j ++)
54                 {
55                     if(inx[j])
56                     {
57                         for(k = 1;k <= n;k ++)
58                         {
59                             if(!iny[k]&&temp > lx[j]+ly[k] - mat[j][k])
60                             temp = lx[j]+ly[k] - mat[j][k];
61                         }
62                     }
63                 }
64                 for(j = 1;j <= n;j ++)
65                 {
66                     if(inx[j])
67                     lx[j] -= temp;
68                     if(iny[j])
69                     ly[j] += temp;
70                 }
71             }
72         }
73     }
74 }
75 int main()
76 {
77     int i,j;
78     while(scanf("%d",&n)!=EOF)
79     {
80         memset(match,-1,sizeof(match));
81         for(i = 1;i <= n;i ++)
82         {
83             for(j = 1;j <= n;j ++)
84             {
85                 scanf("%d",&mat[i][j]);
86             }
87         }
88         KM();
89         int ans = 0;
90         for(i = 1;i <= n;i ++)
91         ans += mat[match[i]][i];
92         printf("%d\n",ans);
93     }
94     return 0;
95 }

 

posted @ 2013-04-17 19:03  Naix_x  阅读(162)  评论(0编辑  收藏  举报