和最大权最大匹配一样,只是在存值的时候存的是负值,在判断if(-c>price[a][b])price[a][b]=-c;这一块还能保证重边的问题;也都是用的KM算法
#include<stdio.h>
#include<string.h>
#define max(a,b) a>b?a:b
#define INF 1<<31-1
int price[105][105];
int lx[105],ly[105];
bool x_vis[105],y_vis[105];
int y_link[105];
int n;
bool dfs(int x)
{
int y;
x_vis[x]=true;
for(y=1;y<=n;y++)
{
if(!y_vis[y] && lx[x]+ly[y] == price[x][y])
{
y_vis[y]=true;
if(y_link[y] == 0|| dfs(y_link[y]))
{
y_link[y]=x;
return true;
}
}
}
return false;
}
void KM_solve()
{
int x,i,j,temp;
memset(ly,0,sizeof(ly));
memset(y_link,0,sizeof(y_link));
for(i=1;i<=n;i++)
lx[i]=-INF;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
lx[i]=max(lx[i],price[i][j]);
for(x=1;x<=n;x++)
{
while(1)
{
memset(x_vis,false,sizeof(x_vis));
memset(y_vis,false,sizeof(y_vis));
if(dfs(x))
break;
else
{
temp=INF;
for(i=1;i<=n;i++)
if(x_vis[i])
for(j=1;j<=n;j++)
if(!y_vis[j] && temp > lx[i] + ly[j]-price[i][j])
temp=lx[i]+ly[j]-price[i][j];
for(i=1;i<=n;i++)
{
if(x_vis[i])
lx[i]-=temp;
if(y_vis[i])
ly[i]+=temp;
}
}
}
}
}
int main()
{
int i,j,m,a,b,c,flag,min;
while(~scanf("%d%d",&n,&m))
{
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
price[i][j]=-INF;
for(i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
if(-c>price[a][b])
price[a][b]=-c;
}
flag=1;
min=0;
KM_solve();
for(i=1;i<=n;i++)
{
if(y_link[i]==0 || price[y_link[i]][i] == -INF)
{
flag=0;
break;
}
min+=price[y_link[i]][i];
}
if(flag)
printf("%d\n",-min);
else
printf("-1\n");
}
return 0;
}