zoukankan      html  css  js  c++  java
  • UVA1658:Admiral

    题意:给定一个有向带权图,求两条不相交(无公共点)的路径且路径权值之和最小,路径由1到v

    题解:这题的关键就在于每个点只能走一遍,于是我们想到以边换点的思想,用边来代替点,怎么代替呢?

    把i拆成i和i',这样经过i就转化为经过i到i'的路径了,从而用最小费用流即可

    #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;
        }
        ll MincostMaxflow(){
            int flow=0;ll cost=0;
            while(SPFA(flow,cost));
            return cost;
        }
    }D;
    int n,m;
    int main()
    {
        while(~scanf("%d%d",&n,&m)){
            D.init(n<<1,0,n);
            D.AddEdge(0,1,2,0);
            for(int i=1;i<=n;i++){
                D.AddEdge(i,i+n,1,0);
            }
            for(int i=1;i<=m;i++){
                int x,y,w;
                scanf("%d%d%d",&x,&y,&w);
                if(x==1||x==n)
                    D.AddEdge(x,y,1,1LL*w);
                else
                    D.AddEdge(x+n,y,1,1LL*w);
            }
            printf("%lld
    ",D.MincostMaxflow());
        }
        return 0;
    }
  • 相关阅读:
    在CentOS-6.9里安装openvswitch-2.5.4
    Django 2.0.7 使用小知识
    微信小程序 存储数据到本地以及本地获取数据
    微信小程序目录结构与配置介绍
    微信小程序视图层介绍及用法
    小程序 wx.request请求
    小程序的启动流程(生命周期)
    小程序的双线程模型
    小程序之基础组件
    小程序之路由跳转
  • 原文地址:https://www.cnblogs.com/w-h-h/p/7847232.html
Copyright © 2011-2022 走看看