您的位置:首页 > 其它

UVA 10480 Sabotage (最大流)

2015-08-14 09:31 447 查看
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82835#problem/J

Sabotage

Description





题目大意:旧政府有一个很庞大的网络系统,可以很方便的指挥他的城市,起义军为了减少伤亡所以决定破坏他们的网络,使他们的首都(1号城市)和最大的城市(2号城市)不能联系,不过破坏不同的网络所花费的代价是不同的,现在起义军想知道最少花费的代价是多少,输出需要破坏的线路。



输入:第一行输入一个N和M,表示城市数和线路数,下面M行,每行有三个整数,表示从破坏城市u到v的线路花费是w。



分析:很明显的最小割问题,我们知道有向图(题目给的是无向图,所以需要建立反边)的最小割等于最大流,所以只需要求出来最大流即可,不过答案需要输出的是路线,其实也很容易解决,在求出来最大流后的残余网络中,只要源点能够到达的点都属于源点集合,到达不了的属于汇点集合,这样就把整个网络分成了两部分,如果原来这两部分有线路连接,那么这条线路肯定是被破坏的,把它输出就行了。

///#pragma comment (linker, "/STACK:102400000,102400000")

#include <iostream>
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <limits>
#include <stack>
#include <vector>
#include <map>

using namespace std;

#define N 1350
#define INF 0xfffffff
#define PI acos (-1.0)
#define EPS 1e-8

struct node1
{
    int v, next, flow;
}edge[N*N];

struct node
{
    int x, y, index;
}p
;

bool cmp (node a, node b)
{
    return a.x < b.x;
}

int head
, layer
, cnt;

void Init ();
void addedge (int u, int v, int flow);
bool BFS (int sa, int en);
int DFS (int sa, int maxflow, int en);
int dinic (int sa, int en);

int main ()
{
    int n, m;
    while (scanf ("%d %d", &n, &m), n+m)
    {
        Init ();
        int a
, b
, flow;

        for (int i=1; i<=m; i++)
        {
            scanf ("%d %d %d", &a[i], &b[i], &flow);///用数组输入,方便后边输出
            addedge (a[i], b[i], flow);
        }

        dinic (1, 2);

        for (int i=1; i<=m; i++)///i一定是到m,不是n
            if ( (layer[a[i]] && !layer[b[i]]) || (!layer[a[i]] && layer[b[i]]) )
                printf ("%d %d\n", a[i], b[i]);///一端与源点相连,一端与汇点相连,并且两点之间有线连接则这条线路一定要被破坏
        puts ("");
    }
    return 0;
}

void Init ()
{
    memset (head, -1, sizeof (head));
    cnt = 0;
}

void addedge (int u, int v, int flow)
{
    edge[cnt].v = v;
    edge[cnt].next = head[u];
    edge[cnt].flow = flow;
    head[u] = cnt++;

    swap (u, v);

    edge[cnt].v = v;
    edge[cnt].next = head[u];
    edge[cnt].flow = flow;
    head[u] = cnt++;

}

bool BFS (int sa, int en)
{
    memset (layer, 0, sizeof (layer));
    queue <int> que;
    que.push (sa);
    layer[sa] = 1;

    while (que.size ())
    {
        sa = que.front (); que.pop ();

        if (sa == en) return true;

        for (int i=head[sa]; i!=-1; i=edge[i].next)
        {
            int v = edge[i].v;
            if (!layer[v] && edge[i].flow)
            {
                layer[v] = layer[sa] + 1;
                que.push (v);
            }
        }
    }
    return false;
}

int DFS (int sa, int maxflow, int en)
{
    if (sa == en) return maxflow;

    int uflow = 0;

    for (int i=head[sa]; i!=-1; i=edge[i].next)
    {
        int v = edge[i].v;
        if (layer[v] == layer[sa]+1 && edge[i].flow)
        {
            int flow = min (maxflow - uflow, edge[i].flow);
            flow = DFS (v, flow, en);

            edge[i].flow -= flow;
            edge[i^1].flow += flow;
            uflow += flow;

            if (uflow == maxflow) break;
        }
    }

    if (!uflow) layer[sa] = 0;
    return uflow;
}

int dinic (int sa, int en)
{
    int maxflow = 0;
    while (BFS (sa, en))
        maxflow += DFS (sa, INF, en);
    return maxflow;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: