解题报告 之 ZOJ2760 How Many Shortest Path
来源:互联网 发布:大数据 杂志 编辑:程序博客网 时间:2024/06/05 15:36
解题报告 之 ZOJ2760 How Many Shortest Path
Description
Given a weighted directed graph, we define the shortest path as the path who has the smallest length among all the path connecting the source vertex to the target vertex. And if two path is said to be non-overlapping, it means that the two path has no common edge. So, given a weighted directed graph, a source vertex and a target vertex, we are interested in how many non-overlapping shortest path could we find out at most.
Input
Input consists of multiple test cases. The first line of each test case, there is an integer number N (1<=N<=100), which is the number of the vertices. Then follows an N * N matrix, represents the directed graph. Each element of the matrix is either non-negative integer, denotes the length of the edge, or -1, which means there is no edge. At the last, the test case ends with two integer numbers S and T (0<=S, T<=N-1), that is, the starting and ending points. Process to the end of the file.
Output
For each test case, output one line, the number of the the non-overlapping shortest path that we can find at most, or "inf" (without quote), if the starting point meets with the ending.
Sample Input
40 1 1 -1-1 0 1 1-1 -1 0 1-1 -1 -1 00 350 1 1 -1 -1-1 0 1 1 -1-1 -1 0 1 -1-1 -1 -1 0 1-1 -1 -1 -1 00 4
Sample Output
21
题目大意:有N个节点,构成一个有向图,给出N*N的邻接矩阵,边权值要么为非负, 要么为-1表示不邻接。再告诉你起点和终点,如果起点和终点相同输出"inf",否则问你从起点到终点一共有多少条没有公共边的最短路?
分析:这是典型的 边不相交最短路的条数 问题。用最大流解决问题。构图是其关键所在。首先我们跑一次Floyd,更新两两点之间的最短距离。然后我们就要开始建图了。大体的思路是,判断所有边是不是某条最短路上的一条边,如果是则加入到流量图中,否则抛弃,再用最大流看看有几条最短路。好了,到了这一步之后我们就该思考如何判断一条边是否是某条最短路的一部分。方法是:dist[from][to] == dist[from][i] + path[i][j] + dist[j][to]
其中dist[i][j]表示 i 到 j 的最短路长度,而path[i][j]表示 i 到 j 的边长度。那么这个等式的意思是,f到t的某条最短路是由f到i的最短路加上j到t的最短路以及i->j这条边组成的。说明i->j 是某条最短路的一部分,那么就在流量图中加边addedge(i ,j ,1) .最后跑一下最大流看看有几条就是几条。
神坑的地方在于邻接表输入中 path[i][i] 不一定输入0 。所以必须手动将path[i][i]设置为0,否则执行最短路部分第一层判断时会出问题。因为dist[from][i] (from==i)本来应该为0,但是你不等于0就错了。
上代码:#include<iostream>#include<algorithm>#include<cstring>#include<cstdio>#include<queue>using namespace std;const int MAXN = 310;const int MAXM = 100100;const int INF = 0x3f3f3f3f;struct Edge{int to, cap, next;};Edge edge[MAXM];int level[MAXN];int head[MAXN];int dist[MAXN][MAXN];int path[MAXN][MAXN];int src, des, cnt;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(){queue<int> q;while (!q.empty())q.pop();memset(level, -1, sizeof level);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;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){int 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)){ans += tem;}}return ans;}int main(){int n, from, to;while (cin >> n){memset(head, -1, sizeof head);cnt = 0;for (int i = 1; i <= n; i++){for (int j = 1; j <= n; j++){scanf( "%d", &path[i][j] );dist[i][j] = path[i][j];}dist[i][i]=path[i][i]=0;}cin >> from >> to;from++;to++;src = from, des = to;if (from == to){cout << "inf" << endl;continue;}for (int k = 1; k <= n; k++)for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++)if ((dist[i][j] > dist[i][k] + dist[k][j] || dist[i][j] == -1) && dist[i][k] != -1 && dist[k][j] != -1)dist[i][j] = dist[i][k] + dist[k][j];if (dist[from][to] == -1){cout << 0 << endl;continue;}for (int i = 1; i <= n; i++){for (int j = 1; j <= n; j++){if (dist[from][to] == dist[from][i] + path[i][j] + dist[j][to] && dist[from][to] != -1 && dist[from][i] != -1&& dist[i][j] != -1 && dist[j][to] != -1)addedge(i, j, 1);}}printf("%d\n", Dinic());}return 0;}
感觉最大流的难度还是在于建图。很多模型不好抽象。
Description
Given a weighted directed graph, we define the shortest path as the path who has the smallest length among all the path connecting the source vertex to the target vertex. And if two path is said to be non-overlapping, it means that the two path has no common edge. So, given a weighted directed graph, a source vertex and a target vertex, we are interested in how many non-overlapping shortest path could we find out at most.
Input
Input consists of multiple test cases. The first line of each test case, there is an integer number N (1<=N<=100), which is the number of the vertices. Then follows an N * N matrix, represents the directed graph. Each element of the matrix is either non-negative integer, denotes the length of the edge, or -1, which means there is no edge. At the last, the test case ends with two integer numbers S and T (0<=S, T<=N-1), that is, the starting and ending points. Process to the end of the file.
Output
For each test case, output one line, the number of the the non-overlapping shortest path that we can find at most, or "inf" (without quote), if the starting point meets with the ending.
Sample Input
40 1 1 -1-1 0 1 1-1 -1 0 1-1 -1 -1 00 350 1 1 -1 -1-1 0 1 1 -1-1 -1 0 1 -1-1 -1 -1 0 1-1 -1 -1 -1 00 4
Sample Output
21
#include<iostream>#include<algorithm>#include<cstring>#include<cstdio>#include<queue>using namespace std;const int MAXN = 310;const int MAXM = 100100;const int INF = 0x3f3f3f3f;struct Edge{int to, cap, next;};Edge edge[MAXM];int level[MAXN];int head[MAXN];int dist[MAXN][MAXN];int path[MAXN][MAXN];int src, des, cnt;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(){queue<int> q;while (!q.empty())q.pop();memset(level, -1, sizeof level);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;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){int 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)){ans += tem;}}return ans;}int main(){int n, from, to;while (cin >> n){memset(head, -1, sizeof head);cnt = 0;for (int i = 1; i <= n; i++){for (int j = 1; j <= n; j++){scanf( "%d", &path[i][j] );dist[i][j] = path[i][j];}dist[i][i]=path[i][i]=0;}cin >> from >> to;from++;to++;src = from, des = to;if (from == to){cout << "inf" << endl;continue;}for (int k = 1; k <= n; k++)for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++)if ((dist[i][j] > dist[i][k] + dist[k][j] || dist[i][j] == -1) && dist[i][k] != -1 && dist[k][j] != -1)dist[i][j] = dist[i][k] + dist[k][j];if (dist[from][to] == -1){cout << 0 << endl;continue;}for (int i = 1; i <= n; i++){for (int j = 1; j <= n; j++){if (dist[from][to] == dist[from][i] + path[i][j] + dist[j][to] && dist[from][to] != -1 && dist[from][i] != -1&& dist[i][j] != -1 && dist[j][to] != -1)addedge(i, j, 1);}}printf("%d\n", Dinic());}return 0;}
感觉最大流的难度还是在于建图。很多模型不好抽象。
- 解题报告 之 ZOJ2760 How Many Shortest Path
- 【zoj2760】【最大流】How Many Shortest Path
- ZOJ2760 How Many Shortest Path(floyd+最大流)
- zoj2760 How Many Shortest Path dinic 最大流
- zoj How Many Shortest Path
- zoj 2760 How Many Shortest Path //MAXFLOW
- zoj 2760 How Many Shortest Path
- hdu 2760 how many shortest path
- Zoj How Many Shortest Path 2760
- ZOJ 2760 How Many Shortest Path
- ZOJ 2760 -- How Many Shortest Path
- ZOJ 2760 How Many Shortest Path
- How Many Tables(解题报告)
- How Many Tables解题报告
- hdu 3631 Shortest Path floyd 解题报告
- ZOJ 1760 How Many Shortest Path(最短路+网络流之最大流)
- HDU1213 How Many Tables 解题报告
- HDU - 1213 How Many Tables 解题报告
- MVC4.0网站发布和部署到IIS7.0上的方法
- apple官方文档翻译:使用NSURLSession(二)
- Hbase 入门简介
- oracle 巡检脚本
- JS判断是否是数组Array
- 解题报告 之 ZOJ2760 How Many Shortest Path
- 11gR2单机通过RMAN恢复到RAC
- GPU硬解码---CUVID
- 杭电5122
- 使用 PyInstaller 把python程序 .py转为 .exe 可执行程序
- UIViewController的 modalPresentationStyle 用法
- procedure_3
- angularJS学习
- 数据结构与算法--排序概述