- 其实就是先最短路,把所有最短路的边保存下来,之后求网络流
- 如果网络流>=2,我们就dfs输出所有的路径即可。
-
-
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<queue>
- using namespace std;
- const int MAXN = 410;
- const int MAXM = 260100;
- const int INF = 0x3f3f3f3f;
- struct Edge
- {
- int to, next, cap;
- };
- Edge edge[MAXM];
- int level[MAXN];
- int head[MAXN];
- int dist[MAXN];
- int map[MAXN][MAXN];
- int src, des, cnt, flag;
- void SPFA(int n)
- {
- int inqueue[MAXN];
- memset( dist, INF, sizeof dist );
- memset( inqueue, 0, sizeof inqueue );
- dist[1] = 0;
- deque<int> dq;
- dq.push_back( 1 );
- inqueue[1] = 1;
- while(!dq.empty())
- {
- int next = dq.front();
- dq.pop_front();
- inqueue[next] = 0;
- for(int i = 1; i <= n; i++)
- {
- if(dist[i] > dist[next] + map[next][i])
- {
- dist[i] = dist[next] + map[next][i];
- if(!inqueue[i])
- {
- if(!dq.empty() && dist[i] > dist[dq.front()])
- dq.push_front( i );
- else
- dq.push_back( i );
- }
- }
- }
- }
- }
- void addedge( int from, int to, int cap )
- {
- edge[cnt].to = to;
- edge[cnt].cap = cap;
- edge[cnt].next = head[from];
- head[from] = cnt++;
- swap( from, to );
- edge[cnt].to = to;
- edge[cnt].cap = 0;
- edge[cnt].next = head[from];
- head[from] = cnt++;
- }
- int bfs()
- {
- memset( level, -1, sizeof level );
- cnt = 0;
- queue<int> q;
- while (!q.empty())
- q.pop();
- level[src] = 0;
- q.push( src );
- while (!q.empty())
- {
- int u = q.front();
- q.pop();
- for (int i = head[u]; i != -1; i = edge[i].next)
- {
- int v = edge[i].to;
- if (edge[i].cap > 0 && level[v] == -1)
- {
- level[v] = level[u] + 1;
- q.push( v );
- }
- }
- }
- return level[des] != -1;
- }
- int dfs( int u, int f )
- {
- if (u == des) return f;
- int tem;
- for (int i = head[u]; i != -1; i = edge[i].next)
- {
- int v = edge[i].to;
- if (edge[i].cap > 0 && level[v] == level[u] + 1)
- {
- tem = dfs( v, min( f, edge[i].cap ) );
- if (tem > 0)
- {
- edge[i].cap -= tem;
- edge[i^1].cap += tem;
- return tem;
- }
- }
- }
- level[u] = -1;
- return 0;
- }
- int Dinic()
- {
- int ans = 0, tem;
- while (bfs())
- {
- while ((tem = dfs( src, INF )) > 0)
- {
- ans += tem;
- }
- }
- return ans;
- }
- void print( int n, int u )
- {
- if(u != n)
- {
- printf( "%d ", u );
- }
- else
- {
- printf( "%d\n", u );
- flag = true;
- return;
- }
- for(int i = head[u]; i != -1&&!flag; i = edge[i].next)
- {
- int v = edge[i].to;
- if(edge[i].cap == 0 && i % 2 == 0)
- {
- edge[i].cap = -1;
- print( n, v );
- }
- }
- }
- int main()
- {
- int n,m;
- while(cin >> n >> m)
- {
- src = 1, des = n;
- memset( head, -1, sizeof head );
- memset( map, INF, sizeof map );
- for(int i = 1; i <= n; i++)
- map[i][i] = 0;
- cnt = 0;
- int a, b, c;
- for(int i = 1; i <= m; i++)
- {
- cin >> a >> b >> c;
- map[a][b] = map[b][a] = c;
- }
- SPFA( n );
- for(int i = 1; i <= n; i++)
- {
- for(int j = 1; j <= n; j++)
- {
- if(dist[i] + map[i][j] == dist[j])
- {
- addedge( i, j, 1 );
- }
- }
- }
- int ans = Dinic();
- if(ans < 2)
- cout << "No solution" << endl;
- else
- {
- print( n,src );
- flag = false;
- print( n, src );
- }
- }
- return 0;
- }
sgu185Two shortest 最短路+网络流+输出路径
最新推荐文章于 2019-03-28 11:48:26 发布