sgu185Two shortest 最短路+网络流+输出路径
2017-10-09 19:19
302 查看
其实就是先最短路,把所有最短路的边保存下来,之后求网络流
如果网络流>=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;
}
如果网络流>=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【最短路+网络流】卡内存输出路径
- SGU 185 Two shortest ★(最短路+网络流)
- SGU 185 Two shortest ★(最短路+网络流)
- zoj 2760 How Many Shortest Path 【最短路 + 最大流】 【求边不重复最短路径条数】
- 各种最短路和路径输出
- hdu 1385(最短路+输出路径)
- SGU 101 输出欧拉路径
- POJ 1895 分层图网络流+输出路径
- poj 3436 ACM Computer Factory 【图论-网络流-最大流-EK-输出路径】
- 路数有限制(w的倍数)的最短路,【二维dijkstra】 双重限制并输出路径和方法数
- PAT ~ L2-001. 紧急救援 (最短路 + 最短路径条数 + 点权最大 + 路径输出)
- Dijkstra求最短路的条数,并输出最短路径和最短路经过的点的最大和
- Bellman Ford+SPFA队列优化(路径还原 输出最短路的路径)
- HDU 1385 Minimum Transport Cost (最短路,并输出路径)
- POJ2457 dijksta求最短路&&输出走过的路径
- UVA 816 Abbott's Revenge BFS求最短路+路径输出(详细注释)
- hdu 3416 最短路+网络流(不重叠最短路径计数)
- sgu 176 上下界网络流最小可行流带输出方案
- sgu 101 Domino【输出欧拉路径】
- sgu 194 上下界网络流可行流判定+输出可行流