从前一个和谐的班级,有 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 }