hdu 3488+hdu 3435(多个环的并)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3488

思路:KM算法求最小权。。。

ps:任何完全图的二分匹配其实就是n个环的并

View Code
 1 #include<iostream>
 2 const int MAXN=222;
 3 const int inf=1<<30;
 4 using namespace std;
 5 int n,m;
 6 int map[MAXN][MAXN];
 7 int lx[MAXN],ly[MAXN];
 8 int match[MAXN];
 9 bool visitx[MAXN],visity[MAXN];
10 
11 int Hungary(int u){
12     visitx[u]=true;
13     for(int i=1;i<=n;i++){
14         if(!visity[i]&&lx[u]+ly[i]==map[u][i]){
15             visity[i]=true;
16             if(match[i]==-1||Hungary(match[i])){
17                 match[i]=u;
18                 return true;
19             }
20         }
21     }
22     return false;
23 }
24 
25 
26 void KM_prefect_match(){
27     int tmp;
28     for(int i=1;i<=n;i++){
29         lx[i]=-inf;                     //初始化应该赋为无穷小
30     }
31     memset(ly,0,sizeof(ly));
32     for(int i=1;i<=n;i++){
33         for(int j=1;j<=n;j++){
34             lx[i]=max(lx[i],map[i][j]);    
35         }
36     }
37     for(int i=1;i<=n;i++)
38     {
39         while(1){
40             memset(visitx,false,sizeof(visitx));
41             memset(visity,false,sizeof(visity));
42             if(Hungary(i))
43                 break;
44             else {
45                 tmp=inf;
46                 for(int j=1;j<=n;j++)if(visitx[j]){   //x在交错树中
47                     for(int k=1;k<=n;k++){
48                         if(!visity[k]&&tmp>lx[j]+ly[k]-map[j][k]){
49                             tmp=lx[j]+ly[k]-map[j][k];
50                         }
51                     }
52                 }
53                 for(int j=1;j<=n;j++){
54                     if(visitx[j])
55                         lx[j]-=tmp;
56                     if(visity[j])
57                         ly[j]+=tmp;
58                 }
59             }
60         }
61     }
62 }
63 
64 
65 int main(){
66     int _case;
67     scanf("%d",&_case);
68     while(_case--){
69         scanf("%d%d",&n,&m);
70         memset(match,-1,sizeof(match));
71         for(int i=1;i<=n;i++){
72             for(int j=1;j<=n;j++){
73                 map[i][j]=-inf;
74             }
75         }
76         for(int i=1;i<=m;i++){
77             int x,y,w;
78             scanf("%d%d%d",&x,&y,&w);
79             if(map[x][y]<-w){
80                 map[x][y]=-w;
81             }
82         }
83         KM_prefect_match();
84         int ans=0;
85         for(int i=1;i<=n;i++){
86             ans+=map[match[i]][i];
87         }
88         printf("%d\n",-ans);
89     }
90     return 0;
91 }

 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3435

View Code
 1 #include<iostream>
 2 const int MAXN=1010;
 3 const int inf=1<<30;
 4 using namespace std;
 5 int n,m;
 6 int map[MAXN][MAXN];
 7 int match[MAXN];
 8 int lx[MAXN],ly[MAXN];
 9 bool visitx[MAXN],visity[MAXN];
10 
11 int Hungary(int u){
12     visitx[u]=true;
13     for(int i=1;i<=n;i++){
14         if(!visity[i]&&lx[u]+ly[i]==map[u][i]){
15             visity[i]=true;
16             if(match[i]==-1||Hungary(match[i])){
17                 match[i]=u;
18                 return true;
19             }
20         }
21     }
22     return false;
23 }
24 
25 
26 void KM_prefect_match(){
27     int tmp;
28     for(int i=1;i<=n;i++){
29         lx[i]=-inf;
30     }
31     memset(ly,0,sizeof(ly));
32     for(int i=1;i<=n;i++){
33         for(int j=1;j<=n;j++){
34             lx[i]=max(lx[i],map[i][j]);
35         }
36     }
37     for(int i=1;i<=n;i++)
38     {
39         while(1){
40             memset(visitx,false,sizeof(visitx));
41             memset(visity,false,sizeof(visity));
42             if(Hungary(i))
43                 break;
44             else {
45                 tmp=inf;
46                 for(int j=1;j<=n;j++)if(visitx[j]){
47                     for(int k=1;k<=n;k++){
48                         if(!visity[k]&&tmp>lx[j]+ly[k]-map[j][k]){
49                             tmp=lx[j]+ly[k]-map[j][k];
50                         }
51                     }
52                 }
53                 for(int j=1;j<=n;j++){
54                     if(visitx[j])
55                         lx[j]-=tmp;
56                     if(visity[j])
57                         ly[j]+=tmp;
58                 }
59             }
60         }
61     }
62 }
63 
64 int main(){
65     int T,_case=1;
66     scanf("%d",&T);
67     while(T--){
68         scanf("%d%d",&n,&m);
69         memset(match,-1,sizeof(match));
70         for(int i=1;i<=n;i++){
71             for(int j=1;j<=n;j++){
72                 map[i][j]=-inf;
73             }
74         }
75         for(int i=1;i<=m;i++){
76             int x,y,w;
77             scanf("%d%d%d",&x,&y,&w);
78             if(map[x][y]<-w){
79                 map[x][y]=map[y][x]=-w;
80             }
81         }
82         KM_prefect_match();
83         printf("Case %d: ",_case++);
84         int ans=0;
85         int flag=false;
86         for(int i=1;i<=n;i++){
87             if(match[i]==-1||map[match[i]][i]==-inf){
88                 flag=true;
89                 break;
90             }
91             ans+=map[match[i]][i];
92         }
93         if(flag){
94             printf("NO\n");
95         }else 
96             printf("%d\n",-ans);
97     }
98     return 0;
99 }
原文地址:https://www.cnblogs.com/wally/p/2996619.html