UVA 11383 KM性质

点击打开链接

题意:一个n*n的矩阵每个格子里有一个正整数w(i,j)你的任务是确定每行一个整数row(i)每列一个整数col(i),对每个格子都有w(i,j)<=row(i)+col(j)所有row(i)和col(i)和尽量小。

思路:本题利用KM算法l(x)+l(y)>=w(x,y)的性质直接可以知道得出的顶标之和即为最小的。

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
const int INF=0x3f3f3f3f;
using namespace std;
int s[505][505],visx[505],visy[505],match[505];
int lx[505],ly[505];
int n,m;
int hungarian(int x){
    int i;
    visx[x]=1;
    for(i=1;i<=m;i++){
        if(!visy[i]&&lx[x]+ly[i]==s[x][i]){
            visy[i]=1;
            if(!match[i]||hungarian(match[i])){
                match[i]=x;
                return 1;
            }
        }
    }
    return 0;
}
int KM(){
    int i,j,k,sum,temp;
    sum=0;
    memset(lx,0,sizeof(lx));
    memset(ly,0,sizeof(ly));
    memset(match,0,sizeof(match));
    for(i=1;i<=n;i++)
    for(j=1;j<=m;j++)
    lx[i]=max(lx[i],s[i][j]);
    for(i=1;i<=n;i++){
        while(1){
            memset(visx,0,sizeof(visx));
            memset(visy,0,sizeof(visy));
            if(hungarian(i))
            break;
            else{
            temp=INF;
            for(j=1;j<=n;j++)
            if(visx[j]){
                for(k=1;k<=m;k++)
                if(!visy[k])
                temp=min(temp,lx[j]+ly[k]-s[j][k]);
            }
            if(temp==INF)
            return -1;
            for(j=1;j<=n;j++)
            if(visx[j])
            lx[j]-=temp;
            for(j=1;j<=m;j++)
            if(visy[j])
            ly[j]+=temp;
            }
        }
    }
    for(i=1;i<=m;i++)
    if(match[i]!=0){
    if(s[match[i]][i]!=-INF)
    sum+=s[match[i]][i];
    else
    return -1;
    }
    return sum;
}
int main(){
    int i,j,a,b,c,ans,num;
    while(scanf("%d",&n)!=EOF){
        m=n;
        for(i=1;i<=n;i++)
        for(j=1;j<=m;j++)
        s[i][j]=-INF;
        for(i=1;i<=n;i++)
        for(j=1;j<=m;j++){
        scanf("%d",&num);
        s[i][j]=num;
        }
        ans=KM();
        for(i=1;i<=n;i++)
        printf("%d ",lx[i]);
        printf("\n");
        for(i=1;i<=m;i++)
        printf("%d ",ly[i]);
        printf("\n");
        printf("%d\n",ans);
    }
    return 0;
}
时间: 2024-08-30 01:12:41

UVA 11383 KM性质的相关文章

uva 11383 Golden Tiger Claw (KM算法)

uva 11383 Golden Tiger Claw 题目大意:给定一个N×N的矩阵,每个格子里都有一个正整数w(i,j).你的任务是给每行确定一个整数row(i), 每列也确定一个整数col(i),使得对于格子(i,j),w(i,j)<=row(i)+col(j).所有row(i)和col(j)的总和最小. 解题思路:KM算法. #include <cstdio> #include <cstring> #include <algorithm> #include

训练指南 UVA - 11383(KM算法的应用 lx+ly &gt;=w(x,y))

layout: post title: 训练指南 UVA - 11383(KM算法的应用 lx+ly >=w(x,y)) author: "luowentaoaa" catalog: true mathjax: true tags: - KM算法 - 训练指南 Golden Tiger Claw UVA - 11383 题意 给一个n*n的矩阵,每个格子中有正整数w[i[j],试为每行和每列分别确定一个数字row[i]和col[i],使得任意格子w[i][j]<=row[i

UVA 11383 - Golden Tiger Claw(二分图完美匹配扩展)

UVA 11383 - Golden Tiger Claw 题目链接 题意:给定每列和每行的和,给定一个矩阵,要求每个格子(x, y)的值小于row(i) + col(j),求一种方案,并且所有行列之和的和最小 思路:A二分图完美匹配的扩展,行列建二分图,权值为矩阵相应位置的值,做一次KM算法后,所有顶标之和就是最小的 代码: #include <cstdio> #include <cstring> #include <cmath> #include <algor

(KM) uva 11383

题意: 给定n*n的矩阵,每个格子有个值s[i][j],现在要求对每行和每列各分配一个值,r[i],c[i]使得对所有的格子都有s[i][j]<=r[i]+c[j]成立,并且sum{r[i]}+sum{c[i]}尽量小. 直接KM啊..SB题啊... #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cstdlib> #includ

UVA 11383 Golden Tiger Claw 金虎爪(KM算法)

题意:给一个n*n的矩阵,每个格子中有正整数w[i][j],试为每行和每列分别确定一个数字row[i]和col[i],使得任意格子w[i][j]<=row[i]+col[j]恒成立.先输row,再输出col,再输出全部总和(总和应尽量小). 思路: KM算法中的顶标就是保持了Lx[i]+ly[j]>=g[i][j]再求最大权和匹配的,但这个最大权和并没有关系.我们可以将row[i]看成一个男的,col[i]看成一个女的,这样男女的总数就相等.一般来说,Lx[i]或Ly[i]仅需要取该行/列中最

UVA 11383 Golden Tiger Claw

Golden Tiger Claw Time Limit: 8000ms Memory Limit: 131072KB This problem will be judged on UVA. Original ID: 1138364-bit integer IO format: %lld      Java class name: Main Omi, Raymondo, Clay and Kimiko are on new adventure- in search of new Shen Gon

UVa 11383 少林决胜(二分图最佳完美匹配)

https://vjudge.net/problem/UVA-11383 题意: 给定一个N×N矩阵,每个格子里都有一个正整数W(i,j).你的任务是给每行确定一个整数row(i),每列也确定一个整数col(i),使得对于任意格子(i,j),w(i,j)<=row(i)+col(j).所有的row(i)和col(i)只和应尽量小. 思路: 利用二分图最佳完美匹配当中的l(x)+l(y)>=w(i,j),直接用KM算法即可. 1 #include<iostream> 2 #inclu

Uva 11609 - Team ( 组合数学 + 二项式性质 + 快速幂取模 )

Uva 11609 - Team ( 组合数学 + 二项式性质 + 快速幂取模 ) 题意: 有N个人,选一个或多个人参加比赛,其中一名当队长,有多少种方案? (如果参赛者完全相同但是队长不同,也算是一种情况) [ 1<=n <= 10^9 ] 分析: 这题要用到组合式公式的性质 转化之后快速幂取模轻松搞定之 代码: //Uva 11609 - Team /* 组合数公式 + 二项式系数性质 + 快速幂 手动自己推 -> F[n] = C(n,1)*1 + C(n,2)*2 + C(n,n

UVA 1349 - Optimal Bus Route Design(KM完美匹配)

UVA 1349 - Optimal Bus Route Design 题目链接 题意:给定一些有向带权边,求出把这些边构造成一个个环,总权值最小 思路:由于环入度出度为1,所以可以把每个点拆成入度点和出度点,然后建图做一次二分图完美匹配即可,注意这题坑点,有重边 代码: #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std