zoukankan      html  css  js  c++  java
  • HDU 5294 Tricks Device 最短路+最大流

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=5294

    题意:

    给你个无向图:

    1、求最少删除几条边就能破坏节点1到节点n的最短路径,

    2、最多能删除多少条边同时保证1到n的最短距离不变。

    题解:

    首先用spfa或dijcstra跑出所有最短路组成的DAG图。

    用这个图跑最大流节能解决第一个问题,用这个图跑一遍bfs最短路就能解决第二个问题。

    然而我在跑最大流的时候竟然把DAG图建成双向的了orz。。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<utility>
    #include<queue>
    #include<cstring>
    using namespace std;
    
    const int maxn = 2222;
    const int INF = 0x3f3f3f3f;
    
    struct Edge {
        int u, v, c, f;
        Edge(int u, int v, int c, int f) :u(u), v(v), c(c), f(f) {}
        Edge() {}
    };
    
    struct Dinic {
        int n, m, s, t;
        vector<Edge> egs;
        vector<int> G[maxn];
        bool vis[maxn];
        int d[maxn];
        int cur[maxn];
    
        void init(int n) {
            this->n = n;
            for (int i = 0; i < n; i++) G[i].clear();
            egs.clear();
        }
    
        void addEdge(int u, int v, int c) {
            egs.push_back(Edge(u, v, c, 0));
            egs.push_back(Edge(v, u, 0, 0));
            m = egs.size();
            G[u].push_back(m - 2);
            G[v].push_back(m - 1);
        }
        bool bfs() {
            memset(vis, 0, sizeof(vis));
            queue<int> Q;
            Q.push(s);
            d[s] = 0;
            vis[s] = 1;
            while (!Q.empty()) {
                int x = Q.front(); Q.pop();
                for (int i = 0; i < G[x].size(); i++) {
                    Edge& e = egs[G[x][i]];
                    if (!vis[e.v] && e.c>e.f) {
                        vis[e.v] = 1;
                        d[e.v] = d[x] + 1;
                        Q.push(e.v);
                    }
                }
            }
            return vis[t];
        }
        int dfs(int x, int a) {
            if (x == t || a == 0) return a;
            int flow = 0, f;
            for (int& i = cur[x]; i < G[x].size(); i++) {
                Edge& e = egs[G[x][i]];
                if (d[x] + 1 == d[e.v] && (f = dfs(e.v, min(a, e.c - e.f)))>0) {
                    e.f += f;
                    egs[G[x][i] ^ 1].f -= f;
                    flow += f;
                    a -= f;
                    if (a == 0) break;
                }
            }
            return flow;
        }
        int Maxflow(int s, int t) {
            this->s = s; this->t = t;
            int flow = 0;
            while (bfs()) {
                memset(cur, 0, sizeof(cur));
                flow += dfs(s, INF);
            }
            return flow;
        }
    }dinic;
    
    int n, m;
    
    vector<pair<int, int> > G[maxn];
    vector<pair<int,int> > pre[maxn];
    
    int inq[maxn], d[maxn];
    void spfa() {
        queue<int> Q;
        memset(inq, 0, sizeof(inq));
        memset(d, 0x3f, sizeof(d));
        d[0] = 0; inq[0] = 1; Q.push(0);
        while (!Q.empty()) {
            int u = Q.front(); Q.pop();
            inq[u] = 0;
            for (int i = 0; i < G[u].size(); i++) {
                int v = G[u][i].first, w = G[u][i].second;
                if (d[v] > d[u] + w) {
                    d[v] = d[u] + w;
                    pre[v].clear(); pre[v].push_back(make_pair(u,w));
                    if (!inq[v]) {
                        Q.push(v); inq[v] = 1;
                    }
                }
                else if (d[v] == d[u] + w) {
                    pre[v].push_back(make_pair(u,w));
                }
            }
        }
    }
    
    int dp[maxn];
    int bfs() {
        memset(dp, -1, sizeof(dp));
        queue<int> Q;
        Q.push(n - 1); dp[n - 1] = 0;
        while (!Q.empty()) {
            int u = Q.front(); Q.pop();
            for (int i = 0; i < pre[u].size(); i++) {
                int v = pre[u][i].first;
                if (dp[v] == -1) {
                    dp[v] = dp[u] + 1;
                    Q.push(v);
                }
            }
        }
        return dp[0];
    }
    
    void init() {
        dinic.init(n);
        for (int i = 0; i < n; i++) G[i].clear(),pre[i].clear();
    }
    
    int main() {
        while (scanf("%d%d", &n, &m) == 2 && n) {
            init();
            for (int i = 0; i < m; i++) {
                int u, v, w;
                scanf("%d%d%d", &u, &v, &w); u--, v--;
                G[u].push_back(make_pair(v, w));
                G[v].push_back(make_pair(u, w));
            }
            spfa();
            for (int i = n - 1; i > 0; i--) {
                for (int j = 0; j < pre[i].size(); j++) {
                    int v = pre[i][j].first;
                    //最后建出来的图应该是DAG图!
                    //dinic.addEdge(i, v, 1);
                    dinic.addEdge(v, i, 1);
                }
            }
            int ans1 = dinic.Maxflow(0,n-1);
            int ans2 = m-bfs();
            printf("%d %d
    ", ans1,ans2);
        }
        return 0;
    }
    
    /*
    8 9
    1 2 2
    2 3 2
    2 4 1
    3 5 3
    4 5 4
    5 8 1
    1 6 2
    6 7 5
    7 8 2
    
    3 3
    1 2 1
    1 3 1
    2 3 1
    
    3 4
    1 2 1
    2 3 0
    1 3 2
    1 3 3
    
    */
  • 相关阅读:
    【Leetcode】23. Merge k Sorted Lists
    【Leetcode】109. Convert Sorted List to Binary Search Tree
    【Leetcode】142.Linked List Cycle II
    【Leetcode】143. Reorder List
    【Leetcode】147. Insertion Sort List
    【Leetcode】86. Partition List
    jenkins 配置安全邮件
    python 发送安全邮件
    phpstorm 同步远程服务器代码
    phpUnit 断言
  • 原文地址:https://www.cnblogs.com/fenice/p/5540067.html
Copyright © 2011-2022 走看看