zoukankan      html  css  js  c++  java
  • J

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

     

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

            printf(" ");
        }

        return 0;
    }
  • 相关阅读:
    删除重复行的DataFrame
    http各个版本(1/1.1/2)对比
    merge()、. join()和concat()合并Pandas中的数据
    openssl windows 平台编译x86 x64
    openssl windows 平台使用 VS2017 编译openssl源码
    openssl des CBC
    openssl des ECB
    ffmpeg des
    网狐棋牌游戏用户数据库 开发文档
    cmake 附加库目录 附加包含头文件目录 链接库 镜像不安全 宏定义 一个完整的cmake小项目
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4720174.html
Copyright © 2011-2022 走看看