SPFA+Dinic HDOJ 5294 Tricks Device

 

题目传送门

 1 /*  2  题意:一无向图,问至少要割掉几条边破坏最短路,问最多能割掉几条边还能保持最短路  3  SPFA+Dinic:SPFA求最短路时,用cnt[i]记录到i最少要几条边,第二个答案是m - cnt[n]  4  最大流==最小割,套个Dinic模板,以后再理解算法。。。  5 */  6 #include <cstdio>  7 #include <algorithm>  8 #include <cstring>  9 #include <queue>  10 #include <vector>  11 using namespace std;  12  13 const int MAXN = 2e3 + 10;  14 const int MAXM = 6e4 + 10;  15 const int INF = 0x3f3f3f3f;  16 struct Edge {  17 int v, w;  18 };  19 struct Flow {  20 int v, cap, rev;  21 };  22 bool vis[MAXN];  23 int cnt[MAXN];  24 int d[MAXN];  25 int lv[MAXN];  26 int it[MAXN];  27 vector<Edge> G[MAXN];  28 vector<Flow> F[MAXN];  29 int n, m;  30  31 void add_edge(int u, int v, int cap) {  32 F[u].push_back ((Flow) {v, cap, (int) F[v].size ()});  33 F[v].push_back ((Flow) {u, 0, (int) F[u].size ()-1});  34 }  35  36 void BFS(int s) {  37 memset (lv, -1, sizeof (lv));  38 queue<int> Q; Q.push (s); lv[s] = 0;  39  40 while (!Q.empty ()) {  41 int u = Q.front (); Q.pop ();  42 for (int i=0; i<F[u].size (); ++i) {  43 Flow &e = F[u][i];  44 if (e.cap > 0 && lv[e.v] < 0) {  45 lv[e.v] = lv[u] + 1;  46  Q.push (e.v);  47  }  48  }  49  }  50 }  51  52 int DFS(int u, int t, int f) {  53 if(u == t) return f;  54 vis[u] = true;  55 for (int i=it[u]; i<F[u].size (); ++i) {  56 Flow &e = F[u][i];  57 if (e.cap > 0 && lv[u] < lv[e.v]) {  58 int d = DFS (e.v, t, min (f, e.cap));  59 if (d > 0) {  60 e.cap -= d; F[e.v][e.rev].cap += d;  61 return d;  62  }  63  }  64  }  65 return 0;  66 }  67  68 int Dinic(int s, int t) {  69 int flow = 0, f;  70 for (; ;) {  71  BFS (s);  72 if (lv[t] < 0) return flow;  73 memset (it, 0, sizeof (it));  74 while ((f = DFS (s, t, INF)) > 0) flow += f;  75  }  76 }  77  78 void build_graph(void) {  79 for (int i=1; i<=n; ++i) {  80 for (int j=0; j<G[i].size (); ++j) {  81 Edge &e = G[i][j];  82 if (d[i] + e.w == d[e.v]) {  83 add_edge (i, e.v, 1);  84 add_edge (e.v, i, 0);  85  }  86  }  87  }  88 }  89  90 void SPFA(int s) {  91 for (int i=1; i<=n; ++i) {  92 d[i] = (i == s) ? 0 : INF;  93 cnt[i] = (i == s) ? 0 : INF;  94  }  95 memset (vis, false, sizeof (vis)); vis[s] = true;  96 queue<int> Q; Q.push (s);  97  98 while (!Q.empty ()) {  99 int u = Q.front (); Q.pop (); 100 vis[u] = false; 101 for (int i=0; i<G[u].size (); ++i) { 102 int v = G[u][i].v, w = G[u][i].w; 103 if (d[v] == d[u] + w) cnt[v] = min (cnt[v], cnt[u] + 1); 104 if (d[v] > d[u] + w) { 105 d[v] = d[u] + w; cnt[v] = cnt[u] + 1; 106 if (!vis[v]) { 107 vis[v] = true; Q.push (v); 108  } 109  } 110  } 111  } 112 } 113 114 int main(void) { //HDOJ 5294 Tricks Device 115 //freopen ("G.in", "r", stdin); 116 117 while (scanf ("%d%d", &n, &m) == 2) { 118 for (int i=1; i<=n; ++i) G[i].clear (); 119 for (int i=1; i<=n; ++i) F[i].clear (); 120 for (int i=1; i<=m; ++i) { 121 int u, v, w; scanf ("%d%d%d", &u, &v, &w); 122  G[u].push_back ((Edge) {v, w}); 123  G[v].push_back ((Edge) {u, w}); 124  } 125 SPFA (1); 126  build_graph (); 127 128 printf ("%d %d\n", Dinic (1, n), m - cnt[n]); 129  } 130 131 return 0; 132 }

 

你可能感兴趣的:(device)