zoukankan      html  css  js  c++  java
  • UVA1349:Optimal Bus Route Design

    题意:给定一个有向带权图,找若干个环,使得每个点属于且仅属于一个环,要求使得环权值之和最小

    题解:发现这题中每个点属于且仅属于一个环,这时候“仅”这种恰好的含义,让我们想到了匹配问题

    当每一个点有且只有一个后继之时,会满足题目的要求,于是把点i拆成i和i',每条边由x连向y',这样做一下二分图最优完美匹配即可

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    #include<vector>
    #define MAXN 5005
    #define ll long long
    #define INF 0x7f7f7f7f
    using namespace std;
    struct Edge{
        int from,to,cap,flow,cost;
        Edge(int u=0,int v=0,int c=0,int f=0,int w=0){
            from=u,to=v,cap=c,flow=f,cost=w;
        }
    };
    struct MCMF{
        int n,m,s,t;
        vector<Edge> edges;
        vector<int> G[MAXN];
        int d[MAXN];
        int p[MAXN];
        int b[MAXN];
        int a[MAXN];
        void init(int n,int s,int t){
            this->n=n;
            this->s=s,this->t=t;
            edges.clear();
            for(int i=0;i<=n;i++){
                G[i].clear();
            }
        }
        void AddEdge(int x,int y,int cap,int cost){
            edges.push_back(Edge(x,y,cap,0,cost));
            edges.push_back(Edge(y,x,0,0,-cost));
            m=edges.size();
            G[x].push_back(m-2);
            G[y].push_back(m-1);
        }
        int SPFA(int &flow,ll &cost){
            memset(d,0x7f,sizeof(d));
            memset(b,0,sizeof(b));
            queue<int> q;
            p[s]=0;
            a[s]=INF;
            d[s]=0;
            q.push(s);
            b[s]=1;
            while(!q.empty()){
                int x=q.front();q.pop();
                b[x]=0;
                for(int i=0;i<G[x].size();i++){
                    Edge& e=edges[G[x][i]];
                    if(e.cap>e.flow&&d[e.to]>d[x]+e.cost){
                        p[e.to]=G[x][i];
                        a[e.to]=min(a[x],e.cap-e.flow);
                        d[e.to]=d[x]+e.cost;
                        if(!b[e.to]){
                            b[e.to]=1;
                            q.push(e.to);
                        }
                    }
                }
            }
            if(d[t]==INF){
                return 0;
            }
            flow+=a[t];
            cost+=1LL*d[t]*a[t];
            for(int i=t;i!=s;i=edges[p[i]].from){
                edges[p[i]].flow+=a[t];
                edges[p[i]^1].flow-=a[t];
            }
            return 1;
        }
        pair<int,ll> MincostMaxflow(){
            int flow=0;ll cost=0;
            while(SPFA(flow,cost));
            return make_pair(flow,cost);
        }
    }D;
    int n;
    int main()
    {
        while(1){
            scanf("%d",&n);
            if(!n)break;
            D.init(n<<1,0,n<<1|1);
            for(int i=1;i<=n;i++){
                D.AddEdge(0,i,1,0);
                D.AddEdge(n+i,n<<1|1,1,0);
            }
            for(int i=1;i<=n;i++){
                while(1){
                    int x;scanf("%d",&x);
                    if(!x)break;
                    int d;scanf("%d",&d);
                    D.AddEdge(i,x+n,1,d);
                }
            }
            pair<int,ll> ans=D.MincostMaxflow();
            if(ans.first==n){
                printf("%lld
    ",ans.second);
            }
            else{
                printf("N
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    SlideShare
    准备SCJP考试
    Sun的过去
    shardingjdbc基础教程
    上万页大数据量的分页查询方案
    shardingjdbc教程 看这一篇就够了
    微服务化的认识
    JDK9对String底层存储的优化
    水平分表
    深入理解Java中的字段与属性的区别
  • 原文地址:https://www.cnblogs.com/w-h-h/p/7850461.html
Copyright © 2011-2022 走看看