zoukankan      html  css  js  c++  java
  • hust 1082 Adding-the-maximum-flow arc

    题目描述

    In the network G(s, t, N, A, U)(s: the souce node, t: the sink node, N: the set of the nodes, A: the set of the arcs, U: the set of the capacity of the arcs), adding a arc's capacity with one unit may make the maximum flow larger. We call this arc as the adding-the-maximum-flow arc. Now the problem is that giving a network G, you must calculate the number of the the adding-the-maximum-flow arcs in the network G.

    输入

    The first line of the input contains an integer T, giving the number of the test cases. For each test case: The first line contains four integers: n, m, s and t(0 < n <= 400, 0 < m <= 10000, 0 < s, t <= n), giving the number of nodes, the number of arcs, the source node and the sink node. And there are m lines followed: each line describe an arc: a, b, c, the arc is from a to b and its capacity is c(0 < a, b <= n, 0 < c < 1000).

    输出

    For each test case, the output contains a single integer which is the number of the adding-the-maximum flow arcs.

    样例输入

    1
    
    4 4 1 4
    
    1 2 3
    
    1 3 5
    
    2 4 2
    
    3 4 6

    样例输出

    2

    提示There may be multiarcs in the network, that is to say there may be more than one arc between two nodes.

    最大流问题,这个题就是求最小割点的数目,我的想法是先求原图的最大流,再把每条边的容量加1,再做一次最大流,第二次的最大流减第一次的最大流就是割点的数目

    #include<map>
    #include<set>
    #include<stack>
    #include<queue>
    #include<cmath>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define  inf 0x0f0f0f0f
    
    using namespace std;
    
    const double pi=acos(-1.0);
    const double eps=1e-8;
    typedef pair<int,int>pii;
    
    const int maxn=10000+10;
    
    struct Edge
    {
        int from,to,cap,flow;
    };
    
    int n,m,s,t;
    vector<Edge>edges;
    vector<int>G[maxn];
    int d[maxn],cur[maxn];
    bool vis[maxn];
    
    void AddEdge(int from,int to,int cap)
    {
        Edge temp;
        temp.cap=cap; temp.flow=0; temp.from=from; temp.to=to;
        edges.push_back(temp);
        temp.cap=0; temp.flow=0; temp.from=to; temp.to=from;
        edges.push_back(temp);
        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);
        d[s]=0;
        vis[s]=1;
        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 Dinic()
    {
        int flow=0;
        while (BFS())
        {
            memset(cur,0,sizeof(cur));
            flow+=DFS(s,inf);
        }
        return flow;
    }
    
    void init()
    {
        for (int i=0;i<=maxn;i++) G[i].clear();
        edges.clear();
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
    
        int T,u[maxn],v[maxn],c[maxn],M;
        scanf("%d",&T);
        while (T--)
        {
            init();
            scanf("%d%d%d%d",&n,&M,&s,&t);
            for (int i=0;i<M;i++)
            {
                scanf("%d%d%d",&u[i],&v[i],&c[i]);
                AddEdge(u[i],v[i],c[i]);
                c[i]++;
            }
            int ans1=Dinic();
            init();
            for (int i=0;i<M;i++)
            AddEdge(u[i],v[i],c[i]);
            int ans2=Dinic();
            printf("%d
    ",ans2-ans1);
        }
        //fclose(stdin);
        return 0;
    }
    至少做到我努力了
  • 相关阅读:
    Use the Microsoft C++ toolset from the command line
    libeay32.dll 和 ssleay32.dll 在1.1.0之后没有了
    libeay32.dll 1.0.2j crash
    VHD VHDX 区别
    char * 转 wchar *
    C++ 0xC0000094: Integer division by zero
    爬取人人网
    伪造请求头向url传递参数爬取百度默认翻译
    爬取百度贴吧
    urllib爬取实例
  • 原文地址:https://www.cnblogs.com/chensunrise/p/3727498.html
Copyright © 2011-2022 走看看