从前一个和谐的班级,有 1,…,nr。

有若干个这样的条件:第 w。

请问这个班级里幸福程度之和最大是多少?

输入格式

第一行三个正整数,nl,nr,m。

接下来 v,u 不会出现两次。

输出格式

第一行一个整数,表示幸福程度之和的最大值。

接下来一行 0。

样例一

input

2 2 3
1 1 100
1 2 1
2 1 1

output

100
1 0

限制与约定

1≤w≤109。

时间限制1s

空间限制MB

 

二分图最大权匹配模板题 KM算法

KM算法略神奇的样子……

http://www.cnblogs.com/wenruo/p/5264235.html

↑感觉这里讲得挺清晰

 

KM算法求的是最大权完备匹配,为了解决两边点数不同的情况,需要虚拟一些点使得两边点数相等

 

↑但是这种DFS写法被无情卡掉

  1 /*by SilverN*/
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<cmath>
  7 #include<vector>
  8 #define LL long long
  9 using namespace std;
 10 const LL INF=1LL<<62;
 11 const int mxn=411;
 12 int read(){
 13     int x=0,f=1;char ch=getchar();
 14     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 15     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
 16     return x*f;
 17 }
 18 void write(LL x){
 19     if(x>9)write(x/10);
 20     putchar(x%10+'0');
 21     return;
 22 }
 23 inline LL mini(LL a,LL b){return a<b?a:b;}
 24 inline LL maxi(LL a,LL b){return a>b?a:b;}
 25 int nL,nR,bl,br,m;
 26 int visL[mxn],visR[mxn];
 27 LL exL[mxn],exR[mxn];
 28 int link[mxn];
 29 LL slack[mxn];
 30 int mp[mxn][mxn];
 31 LL ans=0;
 32 int a[mxn];
 33 int dtime=0;
 34 bool DFS(int u){
 35     visL[u]=dtime;
 36     for(int i=1;i<=nR;i++){
 37         if(visR[i]==dtime)continue;
 38         LL d=exL[u]+exR[i]-mp[u][i];
 39         if(!d){
 40             visR[i]=dtime;
 41             if(!link[i] || DFS(link[i])){
 42                 link[i]=u;
 43                 return 1;
 44             }
 45         }
 46         else slack[i]=min(slack[i],d);
 47     }
 48     return 0;
 49 }
 50 void KM(){
 51 //    memset(link,0,sizeof link);
 52 //    memset(exR,0,sizeof exR);
 53     for(int i=1;i<=nL;i++){
 54         exL[i]=0;
 55         for(int j=1;j<=nR;j++){
 56             exL[i]=maxi(exL[i],mp[i][j]);
 57         }
 58     }
 59     for(int i=1;i<=nL;i++){
 60 //        memset(slack,0x3f,sizeof slack);
 61         for(int j=1;j<=nR;j++)slack[j]=INF;
 62         while(1){//直到匹配成功为止 
 63             dtime++;
 64 //            memset(visL,0,sizeof visL);
 65 //            memset(visR,0,sizeof visR);
 66             if(DFS(i))break;
 67             LL d=INF;
 68             for(int j=1;j<=nR;j++){
 69                 if(visR[j]!=dtime)d=mini(d,slack[j]);
 70             }
 71             for(int j=1;j<=nL;j++){
 72                 if(visL[j]==dtime)exL[j]-=d;
 73                 if(visR[j]==dtime)exR[j]+=d;
 74                 else slack[j]-=d;
 75             }
 76         }
 77     }
 78     ans=0;
 79     nL=bl;nR=br;
 80     for(int i=1;i<=nR;i++){
 81         if(mp[link[i]][i]){
 82             a[link[i]]=i;
 83             ans+=mp[link[i]][i];
 84         }
 85     }
 86     printf("%lld\n",ans);
 87     for(int i=1;i<=nL;i++){
 88         write(a[i]);
 89         putchar(' ');
 90     }
 91     printf("\n");
 92     return;
 93 }
 94 int main(){
 95     int i,j;
 96     nL=read();
 97     nR=read();
 98     bl=nL;br=nR;
 99     nL=max(nL,nR);
100     nR=nL;
101     m=read();
102     int u,v,w;
103     for(i=1;i<=m;i++){
104         u=read();v=read();w=read();
105         mp[u][v]=w;
106     }
107     KM();
108     return 0;
109 }
DFS TLE

相关文章: