Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 380 Accepted Submission(s): 196
1 6 9 1 2 5 2 3 5 3 1 10 3 4 12 4 1 8 4 6 11 5 4 7 5 6 9 6 5 4
42
全图构成哈密顿回路,这种题目已经做过很多,不多说了 #include<cstdio> #include<cstring> #include<vector> using namespace std; const int inf=1<<28; int g[1005][1005];//邻接矩阵 int lx[1005],ly[1005];//顶点标号 bool sx[1005],sy[1005];//是否已经搜索过 int link[1005],n; vector<int> q[1010]; int min(int a,int b) { if(a<b) return a; return b; } bool path(int k) { sx[k]=true; for(int i=1; i<=n; i++) { if(!sy[i]&&(lx[k]+ly[i]==g[k][i])) { sy[i]=1; if(link[i]==-1||path(link[i])) { link[i]=k; return true; } } } return false; } int BestMatch() { int d,sum; memset(ly,0,sizeof(ly)); memset(link,-1,sizeof(link)); for(int i=1; i<=n; i++) { lx[i]=-inf; for(int j=1; j<=n; j++) if(lx[i]<g[i][j]) lx[i]=g[i][j]; } for(int k=1; k<=n; k++) { while(1) { memset(sx,0,sizeof(sx)); memset(sy,0,sizeof(sy)); if(path(k)) break;//匹配成功 d=inf; for(int i=1; i<=n; i++) if(sx[i]) for(int j=1; j<=n; j++) if(!sy[j]) d=min(d,lx[i]+ly[j]-g[i][j]); for(int i=1; i<=n; i++) { if(sx[i]) lx[i]-=d; if(sy[i]) ly[i]+=d; } } } sum=0; for(int i=1; i<=n; i++) { if(link[i]==-1||g[link[i]][i]==-inf) return -1; sum+=g[link[i]][i]; } return -sum; } int main() { int m,T,cas=1; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) q[i].clear(); for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) g[i][j]=inf; for(int i=1; i<=m; i++) { int x,y,c; scanf("%d%d%d",&x,&y,&c); g[x][y]=min(g[x][y],c); } for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) g[i][j]=-g[i][j]; int t=BestMatch(); printf("%d/n",t); } return 0; }