zoukankan      html  css  js  c++  java
  • UVa 10480 Sabotage

    10480  Sabotage:
    The regime of a small but wealthy dictatorship has been abruptly overthrown by an unexpected rebellion.
    Because of the enormous disturbances this is causing in world economy, an imperialist military
    super power has decided to invade the country and reinstall the old regime.
    For this operation to be successful, communication between the capital and the largest city must
    be completely cut. This is a difficult task, since all cities in the country are connected by a computer
    network using the Internet Protocol, which allows messages to take any path through the network.
    Because of this, the network must be completely split in two parts, with the capital in one part and
    the largest city in the other, and with no connections between the parts.
    There are large differences in the costs of sabotaging different connections, since some are much
    more easy to get to than others.
    Write a program that, given a network specification and the costs of sabotaging each connection,
    determines which connections to cut in order to separate the capital and the largest city to the lowest
    possible cost.
    Input:
    Input file contains several sets of input. The description of each set is given below.
    The first line of each set has two integers, separated by a space: First one the number of cities, n in
    the network, which is at most 50. The second one is the total number of connections, m, at most 500.
    The following m lines specify the connections. Each line has three parts separated by spaces: The
    first two are the cities tied together by that connection (numbers in the range 1 − n). Then follows the
    cost of cutting the connection (an integer in the range 1 to 40000000). Each pair of cites can appear at
    most once in this list.
    Input is terminated by a case where values of n and m are zero. This case should not be processed.
    For every input set the capital is city number 1, and the largest city is number 2.


    Output:
    For each set of input you should produce several lines of output. The description of output for each set
    of input is given below:

    The output for each set should be the pairs of cities (i.e. numbers) between which the connection
    should be cut (in any order), each pair on one line with the numbers separated by a space. If there is
    more than one solution, any one of them will do.
    Print a blank line after the output for each set of input.


    Sample Input:
    5 8
    1 4 30
    1 3 70
    5 3 20
    4 3 5
    4 5 15
    5 2 10
    3 2 25
    2 4 50
    5 8
    1 4 30
    1 3 70
    5 3 20
    4 3 5
    4 5 15
    5 2 10
    3 2 25
    2 4 50
    0 0


    Sample Output
    4 1
    3 4
    3 5
    3 2


    4 1
    3 4
    3 5
    3 2

    题意:有n个城市和m条路径,每条路径连接着两个城市,路径后是破坏这两个城市联系所需要的花费,现在想要破坏城市1和城市2之间的联系,问最小的花费,输出其要破坏的路径。

    即求出最大流,在剩余的残余网络中,原本有路径的点,层数为0的点是汇点部分,而层数不为0的点为源点部分,既然它们之间一开始是有联系的,而现在没有联系,说明它们在求出最大流时被破坏了,输出两点即可。

    #include<stdio.h>
    #include<queue>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    
    const int INF=0x3f3f3f3f;
    const int N=1000;
    
    struct node
    {
        int v, cost, next;
    } no[N];
    int layer[N], head[N], k, t;
    
    void Add(int a, int b, int c)
    {
        no[k].v = b;
        no[k].cost = c;
        no[k].next = head[a];
        head[a] = k++;
    
        swap(a, b);
    
        no[k].v = b;
        no[k].cost = c;
        no[k].next = head[a];
        head[a] = k++;
    }
    
    int BFS(int Start, int End)
    {
        int i, u, v;
        queue<int>Q;
    
        memset(layer, 0, sizeof(layer));
    
        Q.push(Start);
        layer[Start] = 1;
    
        while (!Q.empty())
        {
            u = Q.front();
            Q.pop();
    
            if (u == End) return 1;
    
            for (i = head[u]; i != -1; i = no[i].next)
            {
                v = no[i].v;
    
                if (no[i].cost && layer[v] == 0)
                {
                    layer[v] = layer[u]+1;
                    Q.push(v);
                }
            }
        }
    
        return 0;
    }
    
    int DFS(int Start, int End, int mini)
    {
        int i, v, ans, cost = 0;
    
        if (Start == End) return mini;
    
        for (i = head[Start]; i != -1; i = no[i].next)
        {
            v = no[i].v;
    
            if (no[i].cost && layer[v] == layer[Start]+1)
            {
                ans = min(no[i].cost, mini-cost);
                ans = DFS(v, End, ans);
    
                no[i].cost -= ans;
                no[i+1].cost += ans;
                cost += ans;
    
                if (cost == mini) break;
            }
        }
    
        if (cost == 0) layer[Start] = 0;
    
        return cost;
    }
    
    void Dinic(int Start, int End)
    {
        int t=0;
    
        while (BFS(Start, End))
            t += DFS(Start, End, INF);
    }
    int main ()
    {
        int n, m, a, b, c, i, A[N], B[N];
    
        while (scanf("%d%d", &n, &m), n+m)
        {
            memset(head, -1, sizeof(head));
            k = 0;
    
            for (i = 1; i <= m; i++)
            {
                scanf("%d%d%d", &a, &b, &c);
                A[i] = a; B[i] = b;
                Add(a, b, c);
            }
    
            Dinic(1, 2); ///求出最大流的目的是为了在剩余网络中查找被破坏的路径
    
            for (i = 1; i <= m; i++)
            {
                if ((!layer[A[i]] && layer[B[i]]) || (layer[A[i]] && !layer[B[i]])) ///层数为0说明求最大流时肯定经过该点,并且它的父节点的层数肯定不为0,只有这样花费才能达到最小,两点之间的路径被破坏
                printf("%d %d
    ", A[i], B[i]);
            }
            printf("
    ");
        }
    
        return 0;
    }
  • 相关阅读:
    2.配置范例站点站点
    nginx 安装配置+清缓存模块安装
    1.1nginx安装
    1.linux源码安装nginx
    python实现免密码登录lunx服务器
    实现利用公钥私钥免密码登录Linux服务器
    Codeforces Beta Round #61 (Div. 2)
    Codeforces Beta Round #59 (Div. 2)
    Codeforces Beta Round #57 (Div. 2)
    Codeforces Beta Round #55 (Div. 2)
  • 原文地址:https://www.cnblogs.com/syhandll/p/4731802.html
Copyright © 2011-2022 走看看