• UVA1349 Optimal Bus Route Design(KM最佳完美匹配)


    题意:有n个景点,每个景点之间有一些带权有向边,要求你设计一些线路,要求线路是一个圈,并且每个景点只能有一条线路经过,并且只能经过一次(起始点除外),问你,若存在,求这些线路权值的最小和,否则输出"N"

    分析:这题和上一题HDU差不多,只是这题有可能不存在解决方案.同样这题也有重边

    若不存在解决方案,则对于有些点,不存在Left[i]和i的边,故w[Left[i]][i]=-INF;

    http://www.cnblogs.com/arbitrary/archive/2013/04/21/3034424.html

    // File Name: 1349.cpp
    // Author: Zlbing
    // Created Time: 2013/4/21 20:48:33
    
    #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 LL long long
    #define REP(i,r,n) for(int i=r;i<=n;i++)
    #define RREP(i,n,r) for(int i=n;i>=r;i--)
    const int MAXN=105;
    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))
        {
            if(!N)break;
            REP(i,0,N)
                REP(j,0,N)
                w[i][j]=-INF;
            REP(i,1,N)
            {
                while(true){
                    int a,b;
                    scanf("%d",&a);
                    if(!a)break;
                    scanf("%d",&b);
                    w[i][a]=max(w[i][a],-b);
                }
            }
            KM();
            bool flag=true;
            REP(i,1,N)if(w[Left[i]][i]==-INF)flag=false;
    //        REP(i,1,N)
    //        {
    //            REP(j,1,N)
    //                printf("w[%d][%d]=%d ",i,j,w[i][j]);
    //            printf("\n");
    //        }
    //        REP(i,1,N)printf("Left%d\n",Left[i]);
            int ans=0;
            if(flag)
            {
                REP(i,1,N)
                    ans+=-w[Left[i]][i];
                printf("%d\n",ans);
            }
            else printf("N\n");
        }
        return 0;
    }
  • 相关阅读:
    Redis和Memcache的区别分析
    javascript 与jquery为每个p标签增加onclick方法
    repeater单双行颜色不同,gridview repeater DataList 鼠标经过改变背景颜色
    sql 错误提示
    .net获取select控件中的文本内容
    您试图从目录中执行CGI、ISAPI 或其他可执行程序,但该目录不允许执行程序
    html5 调用摄像头
    openfire配置MSSQL说明(数据库设置)
    Openfire 的安装和配置
    JS 等前端学习。
  • 原文地址:https://www.cnblogs.com/arbitrary/p/3034560.html
Copyright © 2020-2023  润新知