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;
}

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

#HDU1853#Cyclic Tour(Km经典模型+环)

Cyclic Tour Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/65535 K (Java/Others) To...
  • its_elaine
  • its_elaine
  • 2017年05月01日 20:41
  • 118

HDU 1853 Cyclic Tour KM算法

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

My Brute (hdu 3315 二分图最大权匹配KM算法)

题意:starvae和xingxing各有n个英雄,starvae的每个英雄有血量Hi和攻击力Ai,xingxing的每个英雄有血量Pi和攻击力Bi,每轮比赛两人各出一个英雄i和j进行对抗,每次sta...
  • u014422052
  • u014422052
  • 2015年07月06日 13:07
  • 708

KM算法的实现

上一篇,我们已经找出了KMP算法对应的数组,这一篇我们将开始用next算法和KMP思想来完成程序: 先贴上代码: package KMPAL; public class KMPAL { publi...
  • ChinMint
  • ChinMint
  • 2017年03月14日 16:24
  • 732

hdu 1853 Cyclic Tour KM

#include #include #define M 310 #define inf 0x3f3f3f3f int n,nx,ny; int link[M],lx[M],ly[M],slack...
  • KIDGIN7439
  • KIDGIN7439
  • 2014年03月15日 21:55
  • 288

hdu 1853 Cyclic Tour【KM】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1853 我的链接:http://acm.hust.edu.cn/vjudge/contest/view...
  • Cfreezhan
  • Cfreezhan
  • 2013年02月26日 15:55
  • 581

hdu 1853 Cyclic Tour //km

Cyclic TourTime Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/65535 K (Java/Others)Total ...
  • hqd_acm
  • hqd_acm
  • 2010年10月06日 10:21
  • 621

对KM算法的理解

一般对KM算法的描述,基本上可以概括成以下几个步骤:  (1) 初始化可行标杆  (2) 用匈牙利算法寻找完备匹配  (3) 若未找到完备匹配则修改可行标杆  (4) 重复(2)(3)直到找到...
  • mosquito_zm
  • mosquito_zm
  • 2017年01月13日 21:45
  • 386

KM算法理解

算法目的:有一个带权二分图,求最大权匹配。O(n^3) KM算法是通过给每个顶点一个标号(叫做顶标)来把求最大权匹配的问题转化为求完备匹配的问题的。设顶点Xi的顶标为A[i],顶点Yi的顶标...
  • Triple_WDF
  • Triple_WDF
  • 2015年11月25日 11:13
  • 1205

KM算法小结

正规的算法解释真看不懂。。。。 果然二分图这东西还是得和泡妞有关才好理解。。。 _ (:зゝ∠) _ 推荐http://www.cnblogs.com/wenruo/p/5264235.html正...
  • Last_Freezen_yue
  • Last_Freezen_yue
  • 2017年03月31日 22:26
  • 229
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:hdu 1853 KM算法
举报原因:
原因补充:

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