hdu 2426

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

思路:就是求最大权匹配,不过一开始map应初始化为inf,然后输入遇到负边的情况就continue。。。

这样最后只需对map[match[i]][i]!=inf的计数,若不等于N,则输出-1,否则,输出ans.

View Code
  1 #include<iostream>
  2 const int MAXN=507;
  3 const int inf=100000000;
  4 using namespace std;
  5 int ans;
  6 int N,M,E;
  7 int map[MAXN][MAXN];
  8 int lx[MAXN],ly[MAXN];
  9 int match[MAXN];
 10 bool visitx[MAXN],visity[MAXN];
 11 
 12 //匈牙利算法
 13 int Hungary(int u){
 14     visitx[u]=true;
 15     for(int i=0;i<M;i++){
 16         if(!visity[i]&&lx[u]+ly[i]==map[u][i]){
 17             visity[i]=true;
 18             if(match[i]==-1||Hungary(match[i])){
 19                 match[i]=u;
 20                 return true;
 21             }
 22         }
 23     }
 24     return false;
 25 }
 26 
 27 int KM_prefect_match(){
 28     int tmp;
 29     memset(lx,0,sizeof(lx));//初始化顶标
 30     memset(ly,0,sizeof(ly));
 31     for(int i=0;i<N;i++){
 32         for(int j=0;j<M;j++){
 33             lx[i]=max(lx[i],map[i][j]);//计算边权最大值
 34         }
 35     }
 36     for(int i=0;i<N;i++)
 37     {
 38         while(1){
 39             memset(visitx,false,sizeof(visitx));
 40             memset(visity,false,sizeof(visity));
 41             if(Hungary(i))//匹配成功
 42                 break;
 43             else {
 44                 //匹配失败,找最小值
 45                 tmp=inf;
 46                 for(int j=0;j<N;j++)if(visitx[j]){  //x在交错树中
 47                     for(int k=0;k<M;k++){
 48                         if(!visity[k]&&tmp>lx[j]+ly[k]-map[j][k]){   //y不在交错树中
 49                             tmp=lx[j]+ly[k]-map[j][k];
 50                         }
 51                     }
 52                 }
 53                 //更新顶标
 54                 for(int j=0;j<N;j++){
 55                     if(visitx[j])
 56                         lx[j]-=tmp;
 57                 }
 58                 for(int j=0;j<M;j++){
 59                     if(visity[j])
 60                         ly[j]+=tmp;
 61                 }
 62             }
 63         }
 64     }
 65     int count=0;
 66     for(int i=0;i<M;i++){
 67         //对map[match[i]][i]!=inf计数
 68         if(match[i]!=-1&&map[match[i]][i]!=-inf){
 69             ans+=map[match[i]][i];
 70             count++;
 71         }
 72     }
 73     if(count==N)return true;
 74     return false;
 75 }
 76 
 77 int main(){
 78     int _case=1;
 79     while(~scanf("%d%d%d",&N,&M,&E)){
 80         ans=0;
 81         for(int i=0;i<N;i++){
 82             for(int j=0;j<M;j++){
 83                 map[i][j]=-inf;
 84             }
 85         }
 86         memset(match,-1,sizeof(match));
 87         for(int i=1;i<=E;i++){
 88             int x,y,value;
 89             scanf("%d%d%d",&x,&y,&value);
 90             if(value>=0)
 91                 map[x][y]=value;
 92         }
 93         printf("Case %d: ",_case++);
 94         if(KM_prefect_match()){
 95             printf("%d\n",ans);
 96         }else {
 97             printf("-1\n");
 98         }
 99     }
100     return 0;
101 }

 

posted @ 2013-03-31 11:46  ihge2k  阅读(321)  评论(0编辑  收藏  举报