HYSBZ 1797 Mincut minimum percentage

Descrption

A, B two countries are at war, which supplies the country's transport network A has N transfer station, M unidirectional path. Wherein the set of i (1≤i≤M) connected to the road vi, ui two transfer stations, then the relay station the relay station ui vi can be reached by the road, that road if cut, the cost required ci. State B now want to find a path cut embodiment, the transfer station that the relay station can not be reached s t, and the sum of the minimum cost of the cutting path. Small cocoa at a glance, which is seeking a minimum cut problem. But love to think of small cocoa is not limited to this. Now he proposes for each one-way road two questions: Question one: Is there a least-cost path cutting program, where the road is cut off? Question two: whether to cut off any program for a least-cost path, the road has been cut off? Now please answer these two questions.

Input

The first row has four positive integer, followed by N, M, s, and t. Lines 2 to (M + 1) lines each a positive integer v 3, u, v denotes a transit point C is connected to a one-way road has a transfer station between the u, v is the starting point of the one-way road, u is the end, cut its cost of c (1≤c≤100000). Note: It may be a number of roads between the two transfer stations directly connected. Adjacent to the same line may have one or more spaces between two numbers.

Output

Each side of a one-way, in an input order, sequentially output line, comprising two non-integer of 0 or 1, respectively, and a question answer to a question II (where 1 represents the output, the output of 0 indicates NO). The same line separated by a space between adjacent two numbers, no extra spaces at the end and beginning of each line.

Sample Input

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

Sample Output

1 0
1 0
0 0
1 0
0 0
1 0
1 0

Hint

The first edge is provided (i + 1) line of the input side number is i, then {1,2}, {6,7}, {2,4,6} is only three minimum cost cutting solution. And they are {1,2,4,6,7}, cross Yes. [Data size] and conventions test data shown in the following table data size data number No. NM NM 1 10 50 6 1000 20000 2 20 200 7 1000 40000 3 200 2000 8 2000 50000 4 200 2000 9 3000 60000 5 1000 20000 10 4000 60000

 Topic analysis

The meaning of problems: given a map, find the minimum cut, then asked FIG Each edge determination whether to satisfy both: 1) whether the road is a minimum cut set of edges, 2) whether the road is all minimal cut set edge; for each edge, the output of the result of the judgment.

Thinking: Dinic start and again, the value of minimum cut, the algorithm then obtains tarjan all strongly connected components in the residual network, where i represents the number of points strongly connected components with Node [i] with, since the residual network without st passage, so there must node [s] = node [t], the process for determination of the two!:

1) We each residue shrunk point network, if one side is the full flow edge, side and end points belong to different strongly connected component, so that the edge must be a minimum cut set side

2) If the two end points of an edge are strongly connected components where the node points s and t [s], node [t] in, then this edge is set contains all cut edges

(Bloggers weak, not concrete proof, it can only directly with the conclusions)

Code area

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<string>
#include<fstream>
#include<vector>
#include<stack>
#include <map>
#include <iomanip>

#define bug cout << "**********" << endl
#define show(x, y) cout<<"["<<x<<","<<y<<"] "
#define LOCAL = 1;
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const int Max = 1e5 + 10;

struct Edge
{
    int from, to, next, flow;
} edge[Max << 1];

int n, m, s, t;
int head[Max], tot;
int dis[Max];
int dfn[Max], low[Max], time_clock;
int node[Max], ans;
int line[Max], now;

void init()
{
    memset(head, -1, sizeof(head));
    tot = 0;
    memset(node, 0, sizeof(node));
    memset(dfn,0,sizeof(dfn));time_clock = 0;
    now = 0;ans = 0;
}

void add(int u, int v, int flow)
{
    edge[tot].from = u;
    edge[tot].to = v;
    edge[tot].flow = flow;
    edge[tot].next = head[u];
    head[u] = tot++;
}

bool bfs()
{
    memset(dis, -1, sizeof(dis));
    queue<int> q;
    q.push(s);
    dis[s] = 0;
    while (!q.empty())
    {
        int u = q.front();
        q.pop();
        for (int i = head[u]; i != -1; i = edge[i].next)
        {
            int v = edge[i].to;
            if (edge[i].flow > 0 && dis[v] == -1)
            {
                dis[v] = dis[u] + 1;
                if (v == t)
                    return true;
                q.push(v);
            }
        }
    }
    return false;
}

int dfs(int u, int flow_in)
{
    if (u == t)
        return flow_in;
    int flow_out = 0;
    for (int i = head[u]; i != -1; i = edge[i].next)
    {
        int v = edge[i].to;
        if (dis[v] == dis[u] + 1 && edge[i].flow > 0)
        {
            int flow = dfs(v, min(flow_in, edge[i].flow));
            if (flow == 0)
                continue;
            flow_in -= flow;
            flow_out += flow;
            edge[i].flow -= flow;
            edge[i^1].flow += flow;
            if (flow_in == 0)
                break;
        }
    }
    return flow_out;
}

int Dinic()
{
    int sum = 0;
    while (bfs())
    {
        sum += dfs(s, inf);
    }
    return sum;
}

void tarjan(int u)
{
    dfn[u] = low[u] = ++time_clock;
    line[++now] = u;
    for(int i = head[u] ;i != -1 ;i = edge[i].next)
    {
        int v = edge[i].to;
        if(edge[i].flow > 0)
        {
            if(!dfn[v])
            {
                tarjan(v);
                low[u] =  min(low[u],low[v]);
            }
            else if(!node[v])
            {
                low[u] = min(low[u],dfn[v]);
            }
        }
    }
    if(dfn[u] == low[u])
    {
        ans++;
        while(line[now] != u)
        {
            node[line[now--]] = ans;
        }
        node[line[now--]] = ans;
    }
}

int main()
{
#ifdef LOCAL
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#endif
    while(scanf("%d%d%d%d",&n,&m,&s,&t)!=EOF)
    {
        init();
        for(int i = 1, u, v, flow ;i <= m ;i++)
        {
            scanf("%d%d%d",&u,&v,&flow);
            add(u,v,flow);add(v,u,0);
        }
        Dinic();
        for(int i = 1 ;i <= n ;i ++)
            if(!dfn[i]) tarjan(i);

        for(int i = 0 ;i < tot ; i += 2)
        {
            if(edge[i].flow) printf("0 0\n");
            else
            {
                if(node[edge[i].from] != node[edge[i].to])
                    printf("1 ");
                else
                    printf("0 ");

                if(node[edge[i].from] == node[s] && node[edge[i].to] == node[t])
                    printf("1\n");
                else
                    printf("0\n");
            }
        }
    }

    return 0;
}
View Code

Guess you like

Origin www.cnblogs.com/winter-bamboo/p/11366123.html