您的位置:首页 > 其它

hdu 1853 KM算法

2013-12-04 23:43 267 查看
#include<stdio.h>

#include<math.h>

#include<string.h>

#define N 200

#define inf 999999999

int Max(int a,int b ) {

return a>b?a:b;

}

int Min(int a,int b) {

return a>b?b:a;

}

int map

,lx
,ly
,s
,t
,link
,n,m,otm
;

int find(int u) {

int i;

s[u]=1;

for(i=1;i<=n;i++)

if(!t[i]&&lx[u]+ly[i]==map[u][i]) {

t[i]=1;

if(link[i]==-1||find(link[i])) {

link[i]=u;

return 1;

}

}

return 0;

}

int KM() {

int i,j,sum=0,d,k,flag;

memset(ly,0,sizeof(ly));

memset(link,-1,sizeof(link));

for(i=1;i<=n;i++) {

lx[i]=-inf;

for(j=1;j<=n;j++)

lx[i]=Max(lx[i],map[i][j]);

}

for(i=1;i<=n;i++) {

while(1) {

memset(s,0,sizeof(s));

memset(t,0,sizeof(t));

if(find(i))break;

d=inf;//这个必须写到这里否则可能导致死循环我感觉4 4 1 3 3 2 1 2 4 1

for(j=1;j<=n;j++)

if(s[j]) {

for(k=1;k<=n;k++)

if(!t[k])

d=Min(d,lx[j]+ly[k]-map[j][k]);

}

for(j=1;j<=n;j++) {

if(s[j])lx[j]-=d;

if(t[j])ly[j]+=d;

}

}

}

flag=0;

for(i=1;i<=n;i++) {

if(link[i]==-1||map[link[i]][i]==-inf) {

flag=1;

break;

}

sum+=map[link[i]][i];

}

if(flag)

sum=-1;

else

sum=-sum;

return sum;

}

int main() {

int i,j,a,b,c;

while(scanf("%d%d",&n,&m)!=EOF) {

for(i=1;i<=n;i++)

for(j=1;j<=n;j++)

map[i][j]=-inf;

while(m--) {

scanf("%d%d%d",&a,&b,&c);

if(-c>map[a][b])

map[a][b]=-c;

}

printf("%d\n",KM());

}

return 0;

}

//another

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<climits>

#include<iostream>

using namespace std;

#define N 550

#define inf 1<<28

int map

,lx
,ly
,s
,t
,link
,n,m,otm
;

int find(int u) {

int i;

s[u]=1;

for(i=1;i<=n;i++)

if(!t[i]) {

if(lx[u]+ly[i]==map[u][i]) {

t[i]= 1;

if(link[i]==-1||find(link[i])) {

link[i]=u;

return 1;

}

}

else

otm[i]=min(otm[i],lx[u]+ly[i]-map[u][i]);

}

return 0;

}

void KM() {

int i,j,sum=0,d,k;

memset(ly,0,sizeof(ly));

memset(link,-1,sizeof(link));

for(i=1;i<=n;i++) {

lx[i]=-inf;

for(j=1;j<=n;j++)

lx[i]=max(lx[i],map[i][j]);

}

for(i=1;i<=n;i++) {

while(1) {

for(j=1;j<=n;j++)

otm[j]=inf;

memset(s,0,sizeof(s));

memset(t,0,sizeof(t));

if(find(i))break;

d=inf;//必须加到while循环里面开始这里一直错

for(k=1;k<=n;k++)

if(!t[k])

d=min(d,otm[k]);

for(j=1;j<=n;j++) {

if(s[j])lx[j]-=d;

if(t[j])ly[j]+=d;

else

otm[j]-=d;

}

}

}

}

int main() {

int i,j,a,b,c,flag,sum;

while(scanf("%d%d",&n,&m)!=EOF) {

for(i=1;i<=n;i++)

for(j=1;j<=n;j++)

map[i][j]=-inf;

while(m--) {

scanf("%d%d%d",&a,&b,&c);

if(-c>map[a][b])

map[a][b]=-c;

}

KM();

flag=false;

sum=0;

for(i=1;i<=n;i++) {

if(link[i]==-1||map[link[i]][i]==-inf) {

flag=true;

break;

}

sum+=map[link[i]][i];

}

if(flag)

sum=-1;

else

sum=-sum;

printf("%d\n",sum);

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: