zoukankan      html  css  js  c++  java
  • UVA11383 Golden Tiger Claw(KM算法)

    刘汝佳新书---训练指南

    题意:给定一个N*N矩阵,每个格子里都有一个正整数w[i][j]。你的任务是给每行确定一个整数row[i],每列确定一个整数col[i],使得对于任意格子(i,j),w[i][j]《=row[i]+col[j]。所有row[i]和col[i]之和应尽量小。

    分析:这题是KM算法的一个副产品,KM算法有等式l(x)+l(y)>=w(x,y).

    // File Name: 11383.cpp
    // Author: zlbing
    // Created Time: 2013/2/27 23:37:40
    
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdlib>
    #include<cstdio>
    #include<set>
    #include<map>
    #include<vector>
    #include<cstring>
    #include<stack>
    #include<cmath>
    #include<queue>
    using namespace std;
    #define CL(x,v); memset(x,v,sizeof(x));
    #define INF 0x3f3f3f3f
    #define MAXN 500+5
    int Left[MAXN];
    int w[MAXN][MAXN];
    int Lx[MAXN],Ly[MAXN];
    bool S[MAXN],T[MAXN];
    int N;
    bool match(int i)
    {
        S[i]=true;
        for(int j=1;j<=N;j++)if(Lx[i]+Ly[j]==w[i][j]&&!T[j])
        {
            T[j]=true;
            if(Left[j]==0||match(Left[j]))
            {
                Left[j]=i;
                return true;
            }
        }
        return false;
    }
    void update(){
        int a=INF;
        for(int i=1;i<=N;i++)if(S[i])
            for(int j=1;j<=N;j++)if(!T[j])
                a=min(a,Lx[i]+Ly[j]-w[i][j]);
        for(int i=1;i<=N;i++){
            if(S[i])Lx[i]-=a;
            if(T[i])Ly[i]+=a;
        }
    }
    void KM()
    {
        for(int i=1;i<=N;i++){
            Left[i]=Lx[i]=Ly[i]=0;
            for(int j=1;j<=N;j++)
            {
                Lx[i]=max(Lx[i],w[i][j]);
            }
        }
        for(int i=1;i<=N;i++){
            for(;;){
                CL(S,0);
                CL(T,0);
                if(match(i))break;
                else update();
            }
        }
    }
    
    int main(){
        while(~scanf("%d",&N))    
        {
            for(int i=1;i<=N;i++)
                for(int j=1;j<=N;j++)
                    scanf("%d",&w[i][j]);
            KM();
            for(int i=1;i<=N;i++)
                if(i==1)printf("%d",Lx[i]);
                else printf(" %d",Lx[i]);
            printf("\n");
            for(int i=1;i<=N;i++)
                if(i==1)printf("%d",Ly[i]);
                else printf(" %d",Ly[i]);
            printf("\n");
            int sum=0;
            for(int i=1;i<=N;i++)
                sum+=Lx[i]+Ly[i];
            printf("%d\n",sum);
    
        }
        return 0;
    }
  • 相关阅读:
    C语言截取从某位置开始指定长度子字符串方法
    vim:放弃hjkl
    vim资源
    PHP和.NET通用的加密解密函数类,均使用3DES加解密 .
    Java与.NET DES加密解密互转
    案例:使用正则表达式的爬虫
    爬虫的正则表达式re模块
    爬虫中Requests模块
    Oracle系列十一 数据处理
    爬虫urllib2 的异常错误处理URLError和HTTPError
  • 原文地址:https://www.cnblogs.com/arbitrary/p/2936063.html
Copyright © 2011-2022 走看看