SGU 185 Two shortest (最大流)
题目:
http://acm.sgu.ru/problem.php?contest=0&problem=185
题意:
给你一个无向图,让你找两条不相交的从1到n的最短路径,并输出
注意:
卡内存,需要用short存数据,否则MLE
方法:
首先从1跑最短路
然后用最大流判是否两条不相交的最短路
然后用dfs输出路径
建图:
从源点向起点1建边$(S,u,2)$,表示流两条路径
从1跑完最短路后,对于任意顶点u,v,如果$d[u]+g[u][v]==d[v]$,则建边$(u,v,1)$,表示边$(u,v)$只能用一次
1 void build() 2 { 3 spfa(1); 4 dinic.init(n + 2); 5 dinic.st = 0; 6 dinic.ed = n; 7 dinic.adde(dinic.st, 1, 2); 8 for (int i = 1; i <= n; i++) 9 for (int j = 1; j <= n; j++) 10 if (d[i] + g[i][j] == d[j]) 11 dinic.adde(i, j, 1); 12 }
然后从S到顶点n跑最大流,如果流量为2,则有解,否则无解
打印路径:
从顶点1开始dfs,如果此边流满且未标记,则输出顶点,并标记此边
做两次上述打印路径的过程
1 void dfsout(int u) 2 { 3 if (u == ed) 4 { 5 printf("%d\n", u); 6 return; 7 } 8 printf("%d ", u); 9 for (int i = head[u]; ~i; i = edge[i].next) 10 { 11 if (i & 1) continue; 12 if (edge[i].cap == edge[i].flow) 13 { 14 edge[i].cap++; 15 dfsout(edge[i].v); 16 break; 17 } 18 } 19 }
1 void solve() 2 { 3 build(); 4 if (d[n] == inf || dinic.Dinic(inf) != 2) 5 { 6 puts("No solution"); 7 return; 8 } 9 dinic.dfsout(1); 10 dinic.dfsout(1); 11 }
代码:
1 /******************************************** 2 *ACM Solutions 3 * 4 *@Title: SGU 185 Two shortest 5 *@Version: 1.0 6 *@Time: 2014-08-28 7 *@Solution: http://www.cnblogs.com/xysmlx/p/xxxxxxx.html 8 * 9 *@Author: xysmlx(Lingxiao Ma) 10 *@Blog: http://www.cnblogs.com/xysmlx 11 *@EMail: xysmlx@163.com 12 * 13 *Copyright (C) 2011-2015 xysmlx(Lingxiao Ma) 14 ********************************************/ 15 // #pragma comment(linker, "/STACK:102400000,102400000") 16 #include <cstdio> 17 #include <iostream> 18 #include <cstring> 19 #include <string> 20 #include <cmath> 21 #include <set> 22 #include <list> 23 #include <map> 24 #include <iterator> 25 #include <cstdlib> 26 #include <vector> 27 #include <queue> 28 #include <stack> 29 #include <algorithm> 30 #include <functional> 31 using namespace std; 32 typedef long long LL; 33 #define pb push_back 34 #define ROUND(x) round(x) 35 #define FLOOR(x) floor(x) 36 #define CEIL(x) ceil(x) 37 const int maxn = 510; 38 const int maxm = 200010; 39 const short inf16 = 0x3f3f; 40 const int inf = 0x3f3f3f3f; 41 const LL inf64 = 0x3f3f3f3f3f3f3f3fLL; 42 const double INF = 1e30; 43 const double eps = 1e-6; 44 const int P[4] = {0, 0, -1, 1}; 45 const int Q[4] = {1, -1, 0, 0}; 46 const int PP[8] = { -1, -1, -1, 0, 0, 1, 1, 1}; 47 const int QQ[8] = { -1, 0, 1, -1, 1, -1, 0, 1}; 48 49 short g[maxn][maxn]; 50 int n, m; 51 int d[maxn]; 52 bool spfa(int s) 53 { 54 bool mark[maxn]; 55 queue<int> Q; 56 memset(d, 0x3f, sizeof(d)); 57 memset(mark, 0, sizeof(mark)); 58 d[s] = 0; 59 Q.push(s); 60 mark[s] = 1; 61 while (Q.size()) 62 { 63 int u = Q.front(); 64 Q.pop(); 65 mark[u] = 0; 66 for (int v = 1; v <= n; v++) 67 { 68 int w = g[u][v]; 69 if (w >= inf16) continue; 70 if (d[u] + w < d[v]) 71 { 72 d[v] = d[u] + w; 73 if (mark[v] == 0) 74 { 75 mark[v] = 1; 76 Q.push(v); 77 } 78 } 79 } 80 } 81 return true; 82 } 83 84 struct DINIC 85 { 86 struct Edge 87 { 88 int u, v; 89 short cap, flow; 90 int next; 91 } edge[maxm]; 92 int head[maxn], en; //需初始化 93 int n, m, d[maxn], cur[maxn]; 94 int st, ed; 95 bool vis[maxn]; 96 void init(int _n = 0) 97 { 98 n = _n; 99 memset(head, -1, sizeof(head)); 100 en = 0; 101 } 102 void addse(int u, int v, int cap, int flow) 103 { 104 edge[en].u = u; 105 edge[en].v = v; 106 edge[en].cap = cap; 107 edge[en].flow = flow; 108 edge[en].next = head[u]; 109 head[u] = en++; 110 cur[u] = head[u]; 111 } 112 void adde(int u, int v, int cap) 113 { 114 addse(u, v, cap, 0); 115 addse(v, u, 0, 0); //注意加反向0 边 116 } 117 bool BFS() 118 { 119 queue<int> Q; 120 memset(vis, 0, sizeof(vis)); 121 Q.push(st); 122 d[st] = 0; 123 vis[st] = 1; 124 while (!Q.empty()) 125 { 126 int u = Q.front(); 127 Q.pop(); 128 for (int i = head[u]; i != -1; i = edge[i].next) 129 { 130 int v = edge[i].v; 131 int w = edge[i].cap - edge[i].flow; 132 if (w > 0 && !vis[v]) 133 { 134 vis[v] = 1; 135 Q.push(v); 136 d[v] = d[u] + 1; 137 if (v == ed) return 1; 138 } 139 } 140 } 141 return false; 142 } 143 int Aug(int u, int a) 144 { 145 if (u == ed) return a; 146 int aug = 0, delta; 147 for (int &i = cur[u]; i != -1; i = edge[i].next) 148 { 149 int v = edge[i].v; 150 int w = edge[i].cap - edge[i].flow; 151 if (w > 0 && d[v] == d[u] + 1) 152 { 153 delta = Aug(v, min(a, w)); 154 if (delta) 155 { 156 edge[i].flow += delta; 157 edge[i ^ 1].flow -= delta; 158 aug += delta; 159 if (!(a -= delta)) break; 160 } 161 } 162 } 163 if (!aug) d[u] = -1; 164 return aug; 165 } 166 int Dinic(int NdFlow) 167 { 168 int flow = 0; 169 while (BFS()) 170 { 171 memcpy(cur, head, sizeof(int) * (n + 1)); 172 flow += Aug(st, inf); 173 /*如果超过指定流量就return 掉*/ 174 if (NdFlow == inf) continue; 175 if (flow > NdFlow) break; 176 } 177 return flow; 178 } 179 180 void dfsout(int u) 181 { 182 if (u == ed) 183 { 184 printf("%d\n", u); 185 return; 186 } 187 printf("%d ", u); 188 for (int i = head[u]; ~i; i = edge[i].next) 189 { 190 if (i & 1) continue; 191 if (edge[i].cap == edge[i].flow) 192 { 193 edge[i].cap++; 194 dfsout(edge[i].v); 195 break; 196 } 197 } 198 } 199 } dinic; 200 201 int kase; 202 void init() 203 { 204 kase++; 205 memset(g, 0x3f, sizeof(g)); 206 } 207 void input() 208 { 209 for (int i = 0; i < m; i++) 210 { 211 int u, v, w; 212 scanf("%d%d%d", &u, &v, &w); 213 g[u][v] = g[v][u] = w; 214 } 215 } 216 void debug() 217 { 218 // 219 } 220 void build() 221 { 222 spfa(1); 223 dinic.init(n + 2); 224 dinic.st = 0; 225 dinic.ed = n; 226 dinic.adde(dinic.st, 1, 2); 227 for (int i = 1; i <= n; i++) 228 for (int j = 1; j <= n; j++) 229 if (d[i] + g[i][j] == d[j]) 230 dinic.adde(i, j, 1); 231 } 232 void solve() 233 { 234 build(); 235 if (d[n] == inf || dinic.Dinic(inf) != 2) 236 { 237 puts("No solution"); 238 return; 239 } 240 dinic.dfsout(1); 241 dinic.dfsout(1); 242 } 243 void output() 244 { 245 // 246 } 247 int main() 248 { 249 // int size = 256 << 20; // 256MB 250 // char *p = (char *)malloc(size) + size; 251 // __asm__("movl %0, %%esp\n" :: "r"(p)); 252 253 // std::ios_base::sync_with_stdio(false); 254 #ifdef xysmlx 255 freopen("in.cpp", "r", stdin); 256 #endif 257 258 kase = 0; 259 while (~scanf("%d%d", &n, &m)) 260 { 261 init(); 262 input(); 263 solve(); 264 output(); 265 } 266 return 0; 267 }
Copyleft © 2013-2015 xysmlx