zoukankan      html  css  js  c++  java
  • Uva 11248 网络扩容

    题目链接:https://vjudge.net/contest/144904#problem/A

    题意:给定一个有向网络,每条边均有一个容量。问是否存在一个从点1到点N,流量为C的流。如果不存在,是否可以恰好修改一条弧的容量,使得存在这样的流?

    分析:

    首先找到最大流,如果发现大于等于C,就得到解,如果小于C的话,枚举最小割。这时,之前的最大流保存下来,清空流量,改变最小割的容量,再求最大流。

    include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 100 + 10;
    const int INF = 0x3f3f3f3f;
    
    struct Edge {
        int from,to,cap,flow;
    };
    
    bool operator < (const Edge& a,const Edge& b) {
        return a.from < b.from || (a.from==b.from&&a.to<b.to);
    }
    
    struct Dinic {
        int n,m,s,t;
        vector<Edge> edges;
        vector<int> G[maxn];
        bool vis[maxn];
        int d[maxn];
        int cur[maxn];
    
        void init(int n) {
            for(int i=0;i<n;i++)
                G[i].clear();
            edges.clear();
        }
    
        void ClearFlow() {
            for(int i=0;i<edges.size();i++) {
                edges[i].flow = 0;
            }
        }
    
        void AddEdge(int from,int to,int cap) {
            edges.push_back((Edge){from,to,cap,0});
            edges.push_back((Edge){to,from,0,0});
            m = edges.size();
            G[from].push_back(m-2);
            G[to].push_back(m-1);
        }
    
        bool BFS() {
            memset(vis,0,sizeof(vis));
            queue<int> Q;
            Q.push(s);
            vis[s] = 1;
            d[s] = 0;
            while(!Q.empty()) {
                int x = Q.front();
                Q.pop();
                for(int i=0;i<G[x].size();i++) {
                    Edge& e = edges[G[x][i]];
                    if(!vis[e.to]&&e.cap>e.flow) {
                        vis[e.to] = 1;
                        d[e.to] = d[x] + 1;
                        Q.push(e.to);
                    }
                }
            }
            return vis[t];
        }
    
    
        int DFS(int x,int a) {
            if(x==t||a==0) return a;
            int flow =0,f;
            for(int& i=cur[x];i<G[x].size();i++) {
                Edge& e = edges[G[x][i]];
                if(d[x]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0) {
                    e.flow +=f;
                    edges[G[x][i]^1].flow -=f;
                    flow +=f;
                    a-=f;
                    if(a==0) break;
                }
            }
            return flow;
        }
    
        int Maxflow(int s,int t) {
            this->s = s;
            this->t = t;
            int flow = 0;
            while(BFS()) {
                memset(cur,0,sizeof(cur));
                flow +=DFS(s,INF);
            }
            return flow;
        }
    
        vector<int> Mincut() {
            vector<int> ans;
            for(int i=0;i<edges.size();i++) {
                Edge& e = edges[i];
                if(vis[e.from]&&!vis[e.to]&&e.cap>0)
                    ans.push_back(i);
            }
            return ans;
        }
    
    
        void Reduce () {
            for(int i=0;i<edges.size();i++)
                edges[i].cap -=edges[i].flow;
        }
    
    };
    
    Dinic g;
    
    int main()
    {
        int kase = 1;
        int n,e,c;
        while(scanf("%d%d%d",&n,&e,&c)==3&&n) {
            g.init(n);
            for(int i=0;i<e;i++) {
                int u,v,cap;
                scanf("%d%d%d",&u,&v,&cap);
                u--;v--;
                g.AddEdge(u,v,cap);
            }
            printf("Case %d: ",kase ++);
            int flow = g.Maxflow(0,n-1);
            if(flow>=c) printf("possible
    ");
    
            else {
                vector<int> cut = g.Mincut();
                g.Reduce();
                vector<Edge> ans;
                for(int i=0;i<cut.size();i++) {
                    Edge& e = g.edges[cut[i]];
                    int temp = e.cap;   ///
                    e.cap = c;
                    g.ClearFlow();
                    if(flow+g.Maxflow(0,n-1)>=c)
                        ans.push_back(e);
                    e.cap = temp;       ///
                }
                if(ans.empty())
                    printf("not possible
    ");
                else {
                    sort(ans.begin(),ans.end());
                    printf("possible option:(%d,%d)",ans[0].from+1,ans[0].to + 1);
                    for(int i=1;i<ans.size();i++) {
                        printf(",(%d,%d)",ans[i].from+1,ans[i].to+1);
                    }
                    puts("");
                }
            }
        }
    
    
    
        return 0;
    }
  • 相关阅读:
    解决ERROR C2011: 'FD_SET' : 'STRUCT' TYPE REDEFINITION问题
    github简单使用教程
    Win32 多线程的创建方法和基本使用
    day 05
    day04
    day03
    day02
    day 06
    day_05
    day 05
  • 原文地址:https://www.cnblogs.com/TreeDream/p/6160144.html
Copyright © 2011-2022 走看看