hdu 1853 KM算法

原创 2013年12月04日 23:43:18
#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;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

KM算法 (HDU 2255 1533 1853 3488 3435 2426 2853)

http://philoscience.iteye.com/blog/1754498   讲解 讲的很详细很好 HDU 2255 #include #include #define ...

HDU 1853 Cyclic Tour KM算法

此题的模型转化比较好 题目说是有向图,把图分成一些环,使得构成这些环总的边权值最小, 环的特性是最少两个点。 观察环这个限制,实际上就是每个点有且只有一个出边,有且只有一个入边,并且不能是...

HDU1853 Cyclic Tour KM算法 模版题

这道题目就是个模版题目,求的是走完图中所有点的最短的路径长度,KM算法 是 最大权匹配,算的是最大权值,但是我们在建图的时候 把权值改为负的就可以了,这样进行KM算法 算出来的 是最大的负数,其实就是...

【二分图完美匹配】【KM算法】hdu2255 奔小康赚大钱 && hdu1853 Cyclic Tour

找了10道题打算刷 结果写了两道不想写了。。。。 因为题都比较水 = =然后英文题看着实在是跪。。。英文渣怎么办嘛。。。 hdu2255 奔小康赚大钱 练代码的水题= =10分钟秒 ...

HDU 1853 Cyclic Tour && HDU 3488 Tour KM算法

昨天用费用流做了这两题,今天用KM做了一下,比费用流快多了,然后,其实并不会KM算法,基本是对着百度抄的,一边抄一边理解。。。 #include #include #include #include...

HDU_1853 Cyclic Tour KM

http://acm.hdu.edu.cn/showproblem.php?pid=1853 题意: 有N个城镇和 M条边,每条边都有一个权值,要求用若干个环把所有的顶点覆盖, 而且每个顶点要求...

HDU1853Cyclic Tour(KM最小费用圈覆盖)

题意:已知城市分为几个不相交的环,每个城市只能属于一个环,一个环最少2个城市,求访问每一个城市一次的最小代价和,代价是城市之间的边。换言之,就是把所有城市访问一遍的最小代价。 解答:以城市之间的路为...

HDU1853-Cyclic Tour KM

Description There are N cities in our country, and M one-way roads connecting them. Now Little Tom ...
  • c_x_a
  • c_x_a
  • 2016年01月01日 03:06
  • 69

HDU 1853 Cyclic Tour(KM或费用流)

题意:有n个点m条边的有向图,一个人可以从一个起点走最终回到起点,每个点只能访问一次。意思是要把这个图分成很多个环,每个点只能属于一个环,求构成这些环的最短路程,若不能满足要求的图就输出-1。 解法...

HDU3722 Card Game KM算法的二分图带权匹配

Problem Address:http://acm.hdu.edu.cn/showproblem.php?pid=3722 【前言】 又搜刮来了一份代码。 用于求二分图的带权匹...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:hdu 1853 KM算法
举报原因:
原因补充:

(最多只允许输入30个字)