hdu 1853 KM算法

来源:互联网 发布:cad画图软件 编辑:程序博客网 时间:2024/06/06 05:54
#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[N][N],lx[N],ly[N],s[N],t[N],link[N],n,m,otm[N];
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[N][N],lx[N],ly[N],s[N],t[N],link[N],n,m,otm[N];
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;
}

原创粉丝点击