【最大流】Sgu 185 _ Two shortest
为了这题我都快wa傻了,简述几点
1.鄙视卡内存的题目
2.鄙视卡内存还卡时间的题目
这题我本来是的思路是求一次最短路,删除这条路上的边,然后再求一次最短路,后来我举了一个例子,将这个方法否定掉了
如果我们按照红色的路径删除最短路,就破坏了另一条最短路。
因此我们换了一个思路,那就是求最大流。
方法是:先求一次最短路,然后将最短路树上的每一条边都加入到一个新的图中,将流量设为1,费用就是边长,建立一个新的图,然后求两次最小费用最大流。
理论上的基础是:
1.最短路树上能到达终点的路径一定是最短路。
2.所有边流量都是1,所以最大流一定不相交。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //sevenkplus bless me 2 #include<iostream> 3 #include<cstdio> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<cctype> 7 #include<cmath> 8 #include<limits.h> 9 #include<iomanip> 10 #include<cstring> 11 #include<fstream> 12 #include<string> 13 #include<queue> 14 #include<stack> 15 #include<set> 16 #include<map> 17 #include<vector> 18 using namespace std; 19 const double pi = 4.0 * atan(1.0); 20 typedef signed long long LL; 21 #define clr(x) memset(x,0,sizeof(x)) 22 #define clro(x) memset(x,-1,sizeof(x)) 23 typedef pair<int,int> pii; 24 const int inf = 9999999; 25 #define sf scanf 26 #define pf printf 27 const int maxn = 500; 28 const int maxm = 160004; 29 bool vis[maxn]; 30 int dis[maxn]; 31 int w[maxn][maxn]; 32 struct Edge{ short from,to,cap,len; }; 33 Edge edges[maxm]; 34 int head[maxn]; 35 int next[maxm]; 36 int pre[maxn]; 37 int tot,deep; 38 queue<short>que; 39 bool spfaa( short s,short t){ 40 int i; 41 short u,v; 42 if( t <= 2 ) return false; 43 clr(vis); 44 for( i=0; i<maxn; ++i) dis[i] = inf; 45 dis[s] = 0; 46 que.push(s); 47 while( !que.empty() ){ 48 u = que.front(); que.pop(); 49 vis[u] = false; 50 for( v=0; v<maxn; ++v){ 51 if( dis[u] + w[u][v] < dis[v] ){ 52 dis[v] = w[u][v] + dis[u]; 53 if( !vis[v] ){ 54 vis[v] = true; 55 que.push(v); 56 } 57 } 58 } 59 } 60 if( dis[t] == inf ) return false; 61 return true; 62 } 63 void addedge( short from, short to, int len){ 64 Edge z; 65 z.from = from, z.to = to, z.cap = 1, z.len = len; 66 edges[tot] = z; 67 next[tot] = head[from]; 68 head[from] = tot++; 69 z.from = to, z.to = from, z.cap = 0, z.len = len; 70 edges[tot] = z; 71 next[tot] = head[to]; 72 head[to] = tot++; 73 } 74 bool spfa( int s,int t){ 75 int i; 76 clr(vis); 77 queue<short>que; 78 for( i=0; i<maxn; ++i) dis[i] = inf; 79 dis[s] = 0; 80 que.push(s); 81 while( !que.empty() ){ 82 short u = que.front(); que.pop(); 83 vis[u] = false; 84 for( i=head[u]; ~i; i = next[i]){ 85 Edge &e = edges[i]; 86 if( e.cap > 0 && dis[u] + e.len < dis[e.to] ){ 87 pre[e.to] = i; 88 dis[e.to] = e.len+ dis[u]; 89 if( !vis[e.to] ){ 90 vis[e.to] = true; 91 que.push(e.to); 92 } 93 } 94 } 95 } 96 if( dis[t] == inf ) return false; 97 return true; 98 } 99 int fl; 100 int N; 101 void dfs(int u, int f) { 102 if (fl) return ; 103 pre[u] = f; 104 if (u == N) { 105 fl = true; 106 return ; 107 } 108 for (int i = head[u]; ~i; i = next[i]) { 109 if (fl) return ; 110 if ((i & 1) == 0 && edges[i].cap == 0) { 111 edges[i].cap = -1; 112 dfs(edges[i].to, u); 113 } 114 } 115 116 } 117 118 void print(int s, int t) { 119 int rec[maxn]; 120 fl = false; 121 dfs(s, -1); 122 int k = 0; 123 for (int u = t; ~u; u = pre[u]) { 124 rec[k++] = u; 125 } 126 for (int i = k - 1; i >= 0; --i) { 127 if (i < k - 1) putchar(' '); 128 printf("%d", rec[i]); 129 } 130 printf("\n"); 131 } 132 void path( int s, int t){ 133 for( int u = t; u != s; u = edges[pre[u] ].from){ 134 edges[pre[u] ].cap -= 1; 135 edges[pre[u]^1 ].cap += 1; 136 } 137 } 138 int maxflow( int s, int t){ 139 int f = 0; 140 while( spfa(s,t) ){ 141 path(s,t); 142 if( ++f == 2 ) return f; 143 } 144 return f; 145 } 146 void init(){ 147 clro(head); 148 for( int i=0; i<maxn; ++i) 149 for( int j=0; j<maxn; ++j) 150 w[i][j] = inf; 151 tot = 0; 152 } 153 bool doit(int n, int m){ 154 N = n; 155 int a,b,c; 156 init(); 157 for( int i=0; i<m; ++i){ 158 sf("%d%d%d",&a,&b,&c); 159 w[a][b] = min( w[a][b], c); 160 w[b][a] = w[a][b]; 161 } 162 if( !spfaa(1,n) ){ 163 puts("No solution"); 164 return false; 165 } 166 for( int i=0; i<maxn; ++i){ 167 for( int j=0; j<maxn; ++j){ 168 if( w[i][j] + dis[i] == dis[j] ) 169 addedge(i,j,w[i][j]); 170 } 171 } 172 return true; 173 } 174 int main(){ 175 int n,m; 176 sf("%d%d",&n,&m); 177 if( doit(n,m) ){ 178 //cout<<fff.maxflow(1,n)<<endl; 179 if( maxflow(1,n) < 2 ){ 180 puts("No solution"); 181 return 0; 182 } 183 } 184 print(1,n); 185 print(1,n); 186 return 0; 187 }