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 }

 

 

 

你可能感兴趣的:(HDU)