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;
}

  

编译人生,运行世界!
原文地址:https://www.cnblogs.com/Running-Time/p/4668538.html