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\n",ans2-ans1);
    }
    //fclose(stdin);
    return 0;
}

 

posted @ 2014-05-14 13:13  Hust_BaoJia  阅读(145)  评论(0编辑  收藏  举报
努力