哈理工oj 1407-Leyni的游戏二分图的最大权匹配

二分图的最大权匹配问题,而且这道题涉及到了要加点,最大权匹配要保证完全匹配的情况下才能得到值,否则dfs函数会一直进行下去,所以需要把原来的矩阵扩充为一个方阵

View Code
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #define inf 0x7fffffff
 5 #define N 205
 6 #define max(x,y) x>y?x:y
 7 #define min(x,y) x<y?x:y
 8 using namespace std;
 9 int map[N][N];
10 bool usedx[N],usedy[N];
11 int match[N];
12 int lx[N],ly[N];
13 int sta[N];
14 int r,c;
15 bool dfs(int x)
16 {
17     int i,temp;
18     usedx[x]=true;
19     for(i=1;i<=c;i++)
20     {
21         temp=lx[x]+ly[i]-map[x][i];
22         if(!usedy[i]&&temp==0)
23         {
24             usedy[i]=true;
25             if(match[i]==-1||dfs(match[i]))
26             {
27                 match[i]=x;
28                 return true;
29             }
30         }
31         else if(sta[i]>temp)
32         sta[i]=temp;
33     }
34     return false;
35 }
36 int km()
37 {
38     int i,j,k,d;
39     memset(lx,0,sizeof(lx));
40     memset(ly,0,sizeof(ly));
41     memset(match,-1,sizeof(match));
42     for(i=1;i<=r;i++)
43     for(j=1;j<=c;j++)
44     lx[i]=max(lx[i],map[i][j]);
45     for(i=1;i<=r;i++)
46     {
47         while(1)
48         {
49             memset(usedx,0,sizeof(usedx));
50             memset(usedy,0,sizeof(usedy));
51             for(j=1;j<=c;j++)
52             sta[j]=inf;
53             if(dfs(i))
54             break;
55             d=inf;
56             for(j=1;j<=c;j++)
57             if(!usedy[j])
58             d=min(sta[j],d);
59             for(j=1;j<=r;j++)
60             if(usedx[j])
61             lx[j]-=d;
62             for(j=1;j<=c;j++)
63             if(usedy[j])
64             ly[j]+=d;
65         }
66     }
67     int res=0;
68     for(i=1;i<=c;i++)
69     if(match[i]!=-1)
70     res+=map[match[i]][i];
71     return res;
72 }
73 int main()
74 {
75     int i,j;
76     while(scanf("%d%d",&r,&c)!=EOF)
77     {
78         memset(map,0,sizeof(map));
79         for(i=1;i<=r;i++)
80         for(j=1;j<=c;j++)
81         scanf("%d",&map[i][j]);
82         r=max(r,c);//扩充为方阵
83         c=max(r,c);
84         printf("%d\n",km());
85     }
86     return 0;
87 }

 

posted @ 2012-05-18 22:17  zhenhai  阅读(187)  评论(0编辑  收藏  举报