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 6 5 1 2 1 2 3 1 3 4 1 4 5 1 5 6 1
42 -1HintIn the first sample, there are two cycles, (1->2->3->1) and (6->5->4->6) whose length is 20 + 22 = 42.
#include<cstdio>
#include<cstring>
#include<algorithm>
const int inf=1<<28;
using namespace std;
int g[505][505],lx[505],ly[505];//顶点标号
bool sx[505],sy[505];//是否已经搜索过
int link[505],n,stack[505];
bool path(int k)//从x[k]寻找增广路
{
sx[k]=true;
for(int i=1; i<=n; i++)
{
if(sy[i]) continue;
int t=ly[i]+lx[k]-g[k][i];
if(t==0)
{
sy[i]=1;
if(link[i]==-1||path(link[i]))
{
link[i]=k;
return true;
}
}
else if(stack[i]>t) stack[i]=t;
}
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]&&g[i][j]!=0) lx[i]=g[i][j];
}
for(int k=1; k<=n; k++)
{
for (int i=1; i<=n; i++) stack[i]=inf;
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 (!sy[i]&&stack[i]<d) d=stack[i];
for(int i=1; i<=n; i++)
if(sx[i]) lx[i]-=d;
for(int i=1; i<=n; i++)
if(sy[i]) ly[i]+=d;
else stack[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;
while(scanf("%d%d",&n,&m)!=EOF)
{
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];
printf("%d/n",BestMatch());
}
return 0;
}