1. 程式人生 > >Sabotage (最小割 /最大流)

Sabotage (最小割 /最大流)

The regime of a small but wealthy dictatorship has been abruptly overthrown by an unexpected rebel-
lion. 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 speci cation 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 le contains several sets of input. The description of each set is given below.
The rst 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

rst two are the cities tied together by that connection (numbers in the range 1

把1和2隔開,隔斷每條邊都有一個花費,求最小花費的情況下,應該切斷那些邊
思路就是求最大流。然後殘留網路下,和源點連通的分在源點一點,和匯點連通的分在匯點
找到了最簡最大流模板
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <queue>
using namespace std;

const int MAXN=100;
const int INF=0x3f3f3f3f;
int g[MAXN][MAXN];//原圖的流量
int flow[MAXN][MAXN];//最後求得最大流的流量
int path[MAXN];
int a[MAXN];
int start,endt;
int n;//頂點數,編號1~n

int maxflow()
{
    queue<int>q;
    memset(flow,0,sizeof(flow));
    int max_flow=0;
    while(1)
    {
        memset(a,0,sizeof(a));
        a[start]=INF;
        while(!q.empty())q.pop();
        q.push(start);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            if(u==endt)break;  
            for(int v=1;v<=n;v++)
            if(!a[v]&&flow[u][v]<g[u][v])
              {
                  path[v]=u;
                  a[v]=min(a[u],g[u][v]-flow[u][v]);
                  q.push(v);
              }
        }
        if(a[endt]==0)break;
        for(int u=endt;u!=start;u=path[u])
        {
            flow[path[u]][u]+=a[endt];
            flow[u][path[u]]-=a[endt];
        }
        max_flow+=a[endt];
    }
    return max_flow;
}
const int MAXM=550;
int x[MAXM],y[MAXM];
int m;
int main()
{
    while(scanf("%d%d",&n,&m)==2)
    {
        if(n==0&&m==0)break;
        memset(g,0,sizeof(g));
        for(int i=0;i<m;i++)
        {
            scanf("%d%d",&x[i],&y[i]);
            scanf("%d",&g[x[i]][y[i]]);
            g[y[i]][x[i]]=g[x[i]][y[i]];
        }
        start=1,endt=2;
        maxflow();
        for(int i=0;i<m;i++)
        {
            if((!a[x[i]]&&a[y[i]]) || (a[x[i]]&&!a[y[i]]) )
                 printf("%d %d\n", x[i], y[i]);
        }
        printf("\n");
    }
    return 0;
}