解题报告 之 SGU185 Two shortest

解题报告 之 SGU185 Two shortest

Description

Yesterday Vasya and Petya quarreled badly, and now they don’t want to see each other on their way to school. The problem is that they live in one and the same house, leave the house at the same time and go at the same speed by the shortest road. Neither of them wants to change their principles, that is why they want to find two separate shortest routes, which won’t make them go along one road, but still they can meet at any junction. They ask you to help them. They number all the junctions with numbers from 1 to N (home and school are also considered as junctions). So their house has the number 1 and the school has the number N, each road connects two junctions exactly, and there cannot be several roads between any two junctions.

Input

The first line contains two integer numbers N and M (2<=N<=400), where M is the number of roads Petya and Vasya noticed. Each of the following M lines contains 3 integers: X, Y and L (1<=X, Y<=N, 1<=L<=10000), where X and Y – numbers of junctions, connected by the road and L is the length of the road.

Output

Write to the first line numbers of the junctions in the way they passed them on the first route. Write to the second line numbers of the junctions in the way they passed them on the second route. If it is impossible to help guys, then output "No solution".

Sample test(s)

Input

6 8

1 2 1

3 2 1

3 4 1

1 3 2

4 2 2

4 5 1

5 6 1

4 6 2

Output

1 3 4 5 61 2 4 6

题目大意:给一个无向图,有n个点,m条边。起点为1,,终点为n。然后问你是否存在两条最短路,其边不重复。如果存在则打印这两条最短路。不存在则输出"No solution"。

分析:题意相对简单,但是卡内存太坑了。不想交最短路模型请见另一篇博文。

ZOJ2760 How Many Shortest Path

首先考虑一般做法,先Floyd跑最短路,让后将所有最短路中的边加入流量图,跑最大流看看有几条最短路。但是这道题卡内存就造成了如果用Floyd的话内存会不够。所以我们必须换,首先想到SPFA,这样就可以让数组dist降维。根据最短路的子路也一定是最短路这一理论,我们遍历i、j,让所有满足添加边,负载为1。

if(dist[i] + map[i][j] == dist[j]){addedge( i, j, 1 );}

然后跑最大流,如果>=2在说明有两条最短路。如果找得到两条最短路,则再dfs搜两次,将满足cap为0且不是逆向边的边打印,然后继续dfs,即可打印出路径。注意在第一次dfs时,如果打印了某边,则将cap设为-1,防止第二次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 );elsedq.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;}最大流刷题暂告一段落,回归集训!

一个人行走,若是寂寞了,寻一座霓虹灯迷离闪烁,

解题报告 之 SGU185 Two shortest

相关文章:

你感兴趣的文章:

标签云: