hdu 1853(Cyclic Tour)

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

二分匹配,求最小权,只要一开始先取相反数,lx初始化的时候取无穷小。。。然后KM一敲,最后输出在取相反数就行了。。。

值得一提的是,我这种渣代码,竟然跑了个rank 1。。。orz。。。

View Code
 1 #include<iostream>

 2 const int MAXN=110;

 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 //匈牙利算法

12 int Hungary(int u){

13     visitx[u]=true;

14     for(int i=1;i<=n;i++){

15         if(!visity[i]&&lx[u]+ly[i]==map[u][i]){

16             visity[i]=true;

17             if(match[i]==-1||Hungary(match[i])){

18                 match[i]=u;

19                 return true ;

20             }

21         }

22     }

23     return false ;

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     while(~scanf("%d%d",&n,&m)){

66         memset(match,-1,sizeof(match));

67         for(int i=1;i<=n;i++){

68             for(int j=1;j<=n;j++){

69                 map[i][j]=-inf;

70             }

71         }

72         for(int i=1;i<=m;i++){

73             int x,y,w;

74             scanf("%d%d%d",&x,&y,&w);

75             if(map[x][y]<-w){

76                 map[x][y]=-w;

77             }

78         }

79         KM_prefect_match();

80         int flag=false;

81         int ans=0;

82         for(int i=1;i<=n;i++){

83             if(match[i]==-1||map[match[i]][i]==-inf){

84                 flag=true;

85                 break;

86             }

87             ans+=map[match[i]][i];

88         }

89         if(flag){

90             printf("-1\n");

91         }else 

92             printf("%d\n",-ans);

93     }

94     return 0;

95 }

 

 

你可能感兴趣的:(HDU)