J - Sabotage - UVA 10480(最大流)

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

 

输入:第一行输入一个N和M,表示城市数和线路数,下面M行,每行有三个整数,表示从破坏城市u到v的线路花费是w。
 
分析:很明显的最小割问题,我们知道有向图(题目给的是无向图,所以需要建立反边)的最小割等于最大流,所以只需要求出来最大流即可,不过答案需要输出的是路线,其实也很容易解决,在求出来最大流后的残余网络中,只要源点能够到达的点都属于源点集合,到达不了的属于汇点集合,这样就把整个网络分成了两部分,如果原来这两部分有线路连接,那么这条线路肯定是被破坏的,把它输出就行了。
下面是AC代码。
=============================================================================================================================
#include
#include
#include
#include< string.h>
using  namespace std;

const  int MAXN =  105;
const  int oo = 1e9+ 7;

int G[MAXN][MAXN], Layer[MAXN];
int x[MAXN* 5], y[MAXN* 5];

bool BFS( int start,  int End,  int N)
{
    memset(Layer,  0sizeof(Layer));
    queue< int> Q; Q.push(start);
    Layer[start] =  1;

     while(Q.size())
    {
         int i = Q.front();Q.pop();

         if(i == End) return  true;

         for( int j= 1; j<=N; j++)
        {
             if(!Layer[j] && G[i][j])
            {
                Layer[j] = Layer[i] +  1;
                Q.push(j);
            }
        }
    }

     return  false;
}
int DFS( int i,  int MaxFlow,  int End,  int N)
{
     if(i == End) return MaxFlow;

     int iflow =  0;

     for( int j= 1; j<=N; j++)
    {
         if(Layer[j]- 1 == Layer[i] && G[i][j])
        {
             int flow = min(MaxFlow-iflow, G[i][j]);
            flow = DFS(j, flow, End, N);

            G[i][j] -= flow;
            G[j][i] += flow;
            iflow += flow;

             if(iflow == MaxFlow)
                 break;
        }
    }

     if(iflow ==  0)
        Layer[i] =  0;

     return iflow;
}
int Dinic( int start,  int End,  int N)
{
     int MaxFlow =  0;

     while( BFS(start, End, N) ==  true )
        MaxFlow += DFS(start, oo, End, N);

     return MaxFlow;
}

int main()
{
     int N, M;

     while(scanf( " %d%d ", &N, &M) != EOF && M+N)
    {
         int i, u, v, flow;
         int w[MAXN][MAXN]={ 0};

        memset(G,  0sizeof(G));

         for(i= 1; i<=M; i++)
        {
            scanf( " %d%d%d ", &u, &v, &flow);
            x[i] = u, y[i] = v;
            G[u][v] = G[v][u] = flow;
            w[u][v] = w[v][u] = flow;
        }

        Dinic( 12, N);

         for(i= 1; i<=M; i++)
        {
             if(!Layer[x[i]] && Layer[y[i]] || Layer[x[i]] && !Layer[y[i]])
                printf( " %d %d\n ", x[i], y[i]);
        }

        printf( " \n ");
    }

     return  0;
}

转载于:https://www.cnblogs.com/liuxin13/p/4720174.html

你可能感兴趣的:(J - Sabotage - UVA 10480(最大流))