zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    c#基础之集合
    找出子字符串在字符串中的所有索引
    c# 排序
    C#基础之枚举
    验证用户名不为空并且不存在
    验证用户名和密码,输入三次不正确就锁定账号
    c#基础
    linux使用
    python之logging模块
    手写MyBatis,纯手工打造开源框架(第三篇:运筹帷幄)
  • 原文地址:https://www.cnblogs.com/wally/p/2991545.html
Copyright © 2011-2022 走看看