Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 2462 Accepted Submission(s): 1222
题意:让找一个环,费用最小,这个环要包括所有的点,km算法;不过要建负边;负的最大匹配等于最小匹配,而且要考虑重边的情况;大神们好多用费用流写的。。。膜拜;
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> using namespace std; const int INF=0x3f3f3f3f; const double PI=acos(-1.0); #define mem(x,y) memset(x,y,sizeof(x)) typedef long long LL; #define SI(x) scanf("%d",&x) #define SL(x) scanf("%lld",&x) #define T_T while(T--) #define F(i,x) for(i=1;i<=x;i++) #define PR(x) printf("%d",x) #define PL(x) printf("%lld",x) #define p_ printf(" ") const int MAXN=210; const int MAXM=30010; int mp[MAXN][MAXN]; int lx[MAXN],ly[MAXN],usdx[MAXN],usdy[MAXN],link[MAXN]; int N; bool dfs(int x){ int i,j; usdx[x]=1; F(i,N){ if(!usdy[i]&&lx[x]+ly[i]==mp[x][i]){ usdy[i]=1; if(link[i]==-1||dfs(link[i])){ link[i]=x;return true; } } } return false; } int km(){ mem(ly,0);mem(link,-1); int i,j,k; F(i,N){ lx[i]=-INF; F(j,N){ lx[i]=max(lx[i],mp[i][j]); } } F(i,N){ mem(usdx,0);mem(usdy,0); while(!dfs(i)){ int d=INF; F(j,N){ if(usdx[j]){ F(k,N) if(!usdy[k]) d=min(d,lx[j]+ly[k]-mp[j][k]); } } F(j,N){ if(usdx[j])lx[j]-=d; if(usdy[j])ly[j]+=d; } mem(usdx,0);mem(usdy,0); } } int ans=0; F(i,N)ans+=lx[i]+ly[i]; return -ans; } void initial(){ int i,j; F(i,N)F(j,N)mp[i][j]=-INF; } int main(){ int T,M; SI(T); T_T{ int a,b,c; SI(N);SI(M); initial(); while(M--){ SI(a);SI(b);SI(c); if(-c>mp[a][b])mp[a][b]=-c; } printf("%d\n",km()); } return 0; }
原文:http://www.cnblogs.com/handsomecui/p/4999283.html