【最大流】Sgu 185 _ Two shortest

为了这题我都快wa傻了,简述几点

1.鄙视卡内存的题目

2.鄙视卡内存还卡时间的题目

这题我本来是的思路是求一次最短路,删除这条路上的边,然后再求一次最短路,后来我举了一个例子,将这个方法否定掉了

如果我们按照红色的路径删除最短路,就破坏了另一条最短路。

 

因此我们换了一个思路,那就是求最大流。

方法是:先求一次最短路,然后将最短路树上的每一条边都加入到一个新的图中,将流量设为1,费用就是边长,建立一个新的图,然后求两次最小费用最大流。

理论上的基础是:

1.最短路树上能到达终点的路径一定是最短路。

2.所有边流量都是1,所以最大流一定不相交。

View Code
  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 }

 

 

 

posted @ 2012-12-20 19:05  masterhe  阅读(177)  评论(0编辑  收藏  举报