• 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
    
    */
  • 相关阅读:
    《maven实战》笔记(5)----maven的版本
    《maven实战》笔记(4)----maven的仓库
    《maven实战》笔记(2)----一个简单maven项目的搭建,测试和打包
    《maven实战》笔记(1)----maven的初识
    web项目jsp出现The superclass javax.servlet.http.HttpServlet was not found on the Java Build Path错误
    如何在国内使用google
    js实现仿购物车加减效果
    关于行内元素之间有空隙的问题,例如span与input之间
    jquery遍历DOM方法总结
    左侧手风琴下拉菜单导航(网页常用功能)
  • 原文地址:https://www.cnblogs.com/fenice/p/5540067.html
Copyright © 2020-2023  润新知