zoukankan      html  css  js  c++  java
  • SPFA+Dinic HDOJ 5294 Tricks Device

    题目传送门

    /*
        题意:一无向图,问至少要割掉几条边破坏最短路,问最多能割掉几条边还能保持最短路 
        SPFA+Dinic:SPFA求最短路时,用cnt[i]记录到i最少要几条边,第二个答案是m - cnt[n]
                    最大流==最小割,套个Dinic模板,以后再理解算法。。。
     */
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    #include <vector>
    using namespace std;
    
    const int MAXN = 2e3 + 10;
    const int MAXM = 6e4 + 10;
    const int INF = 0x3f3f3f3f;
    struct Edge {
        int v, w;
    };
    struct Flow {
        int v, cap, rev;
    };
    bool vis[MAXN];
    int cnt[MAXN];
    int d[MAXN];
    int lv[MAXN];
    int it[MAXN];
    vector<Edge> G[MAXN];
    vector<Flow> F[MAXN];
    int n, m;
    
    void add_edge(int u, int v, int cap)    {
        F[u].push_back ((Flow) {v, cap, (int) F[v].size ()});
        F[v].push_back ((Flow) {u, 0, (int) F[u].size ()-1});
    }
    
    void BFS(int s) {
        memset (lv, -1, sizeof (lv));
        queue<int> Q;   Q.push (s); lv[s] = 0;
    
        while (!Q.empty ()) {
            int u = Q.front (); Q.pop ();
            for (int i=0; i<F[u].size (); ++i)  {
                Flow &e = F[u][i];
                if (e.cap > 0 && lv[e.v] < 0)   {
                    lv[e.v] = lv[u] + 1;
                    Q.push (e.v);
                }
            }
        }
    }
    
    int DFS(int u, int t, int f)    {
        if(u == t)  return f;
        vis[u] = true;
        for (int &i=it[u]; i<F[u].size (); ++i)  {
            Flow &e = F[u][i];
            if (e.cap > 0 && lv[u] < lv[e.v])   {
                int d = DFS (e.v, t, min (f, e.cap));
                if (d > 0)  {
                    e.cap -= d; F[e.v][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }
    
    int Dinic(int s, int t)  {
        int flow = 0, f;
        for (; ;)   {
            BFS (s);
            if (lv[t] < 0)  return flow;
            memset (it, 0, sizeof (it));
            while ((f = DFS (s, t, INF)) > 0)   flow += f;
        }
    }
    
    void build_graph(void)  {
        for (int i=1; i<=n; ++i)    {
            for (int j=0; j<G[i].size (); ++j)  {
                Edge &e = G[i][j];
                if (d[i] + e.w == d[e.v])   {
                    add_edge (i, e.v, 1);
                    add_edge (e.v, i, 0);
                }
            }
        }
    }
    
    void SPFA(int s)    {
        for (int i=1; i<=n; ++i)    {
            d[i] = (i == s) ? 0 : INF;
            cnt[i] = (i == s) ? 0 : INF;
        }
        memset (vis, false, sizeof (vis));  vis[s] = true;
        queue<int> Q;   Q.push (s);
    
        while (!Q.empty ()) {
            int u = Q.front (); Q.pop ();
            vis[u] = false;
            for (int i=0; i<G[u].size (); ++i)  {
                int v = G[u][i].v, w = G[u][i].w;
                if (d[v] == d[u] + w)   cnt[v] = min (cnt[v], cnt[u] + 1);
                if (d[v] > d[u] + w)   {
                    d[v] = d[u] + w;    cnt[v] = cnt[u] + 1;
                    if (!vis[v])    {
                        vis[v] = true;  Q.push (v);
                    }
                }
            }
        }
    }
    
    int main(void)  {       //HDOJ 5294 Tricks Device
        //freopen ("G.in", "r", stdin);
    
        while (scanf ("%d%d", &n, &m) == 2) {
            for (int i=1; i<=n; ++i)    G[i].clear ();
            for (int i=1; i<=n; ++i)    F[i].clear ();
            for (int i=1; i<=m; ++i)    {
                int u, v, w;    scanf ("%d%d%d", &u, &v, &w);
                G[u].push_back ((Edge) {v, w});
                G[v].push_back ((Edge) {u, w});
            }
            SPFA (1);
            build_graph ();
    
            printf ("%d %d
    ", Dinic (1, n), m - cnt[n]);
        }
    
        return 0;
    }
    

      

    编译人生,运行世界!
  • 相关阅读:
    招聘里常见的沟通能力到底是什么
    C++服务器linux开发环境管理
    网络游戏通信协议双向迭代加密
    win10控制台程序printf死锁问题
    手游系统逻辑档案之通信协议
    STL插入删除和查询测试
    MATLAB复制图片时边框大的问题
    2019网易笔试题C++--丰收
    暴力求解最长公共子串
    顺时针打印矩阵
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4668538.html
Copyright © 2011-2022 走看看