ZOJ 2760 How Many Shortest Path 网络最大流
来源:互联网 发布:soa mlc 知乎 编辑:程序博客网 时间:2024/06/07 12:39
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2760
题意:给一个有向图,求里面最短路的条数?
解法:
floyd+最大流。针对网络流算法而建的模型中,s-t对应于实际中每一种方案,所以此题中的s-t就对应于题目
中的一条源点到汇点的最短路径,最大流就是最短路径条数。
接下来就是怎么建模的问题:既然s-t对应于一条最短路径,那么s-t路径上的每一条边都是路径中的最短边。
所以首先用floyd求出点到点的最短路径,然后枚举每条边判断是否是最短路径上的边,若是,则加入到新建
的图中,权值为1。
#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;const int maxn = 510;const int maxm = 100010;const int inf = 0x3f3f3f3f;struct G{ int v, cap, next; G() {} G(int v, int cap, int next) : v(v), cap(cap), next(next) {}} E[maxm];int p[maxn], T;int d[maxn], temp_p[maxn], qw[maxn]; //d顶点到源点的距离标号,temp_p当前狐优化,qw队列void init(){ memset(p, -1, sizeof(p)); T = 0;}void add(int u, int v, int cap){ E[T] = G(v, cap, p[u]); p[u] = T++; E[T] = G(u, 0, p[v]); p[v] = T++;}bool bfs(int st, int en, int n){ int i, u, v, head, tail; for(i = 0; i <= n; i++) d[i] = -1; head = tail = 0; d[st] = 0; qw[tail] = st; while(head <= tail) { u = qw[head++]; for(i = p[u]; i + 1; i = E[i].next) { v = E[i].v; if(d[v] == -1 && E[i].cap > 0) { d[v] = d[u] + 1; qw[++tail] = v; } } } return (d[en] != -1);}int dfs(int u, int en, int f){ if(u == en || f == 0) return f; int flow = 0, temp; for(; temp_p[u] + 1; temp_p[u] = E[temp_p[u]].next) { G& e = E[temp_p[u]]; if(d[u] + 1 == d[e.v]) { temp = dfs(e.v, en, min(f, e.cap)); if(temp > 0) { e.cap -= temp; E[temp_p[u] ^ 1].cap += temp; flow += temp; f -= temp; if(f == 0) break; } } } return flow;}int dinic(int st, int en, int n){ int i, ans = 0; while(bfs(st, en, n)) { for(i = 0; i <= n; i++) temp_p[i] = p[i]; ans += dfs(st, en, inf); } return ans;}//最大流int ma[maxn][maxn], ma1[maxn][maxn];int main(){ int n, st, en; while(scanf("%d",&n)!=EOF){ init(); for(int i=1; i<=n; i++){ for(int j=1; j<=n; j++){ scanf("%d", &ma[i][j]); if(ma[i][j]==-1) ma[i][j]=inf; if(i==j) ma[i][j]=0; ma1[i][j]=ma[i][j]; } } scanf("%d%d",&st,&en); if(st==en){ printf("inf\n"); continue; } st++,en++; for(int k=1; k<=n; k++){ for(int i=1; i<=n; i++){ if(ma[i][k]==inf) continue; for(int j=1; j<=n; j++){ if(ma[k][j]==inf) continue; ma[i][j] = min(ma[i][j], ma[i][k]+ma[k][j]); } } } for(int i=1; i<=n; i++){ if(ma[st][i]==inf) continue; for(int j=1; j<=n; j++){ if(i==j) continue; if(ma1[i][j]==inf) continue; if(ma[j][en]==inf) continue; if(ma[st][en]==ma[st][i]+ma1[i][j]+ma[j][en]) add(i,j,1); } } int ans = dinic(st,en,n); printf("%d\n", ans); } return 0;}
0 0
- ZOJ 2760 - How Many Shortest Path(网络流’最大流)
- ZOJ 2760 How Many Shortest Path 网络最大流
- ZOJ 2760 How Many Shortest Path(floyd+最大流)
- ZOJ 2760 How Many Shortest Path 最短路+最大流
- ZOJ 2760 How Many Shortest Path 最大流+Floyed
- ZOJ 2760 How Many Shortest Path(floyd + 最大流)
- ZOJ 2760 How Many Shortest Path 最短路+最大流
- ZOJ 1760 How Many Shortest Path(最短路+网络流之最大流)
- ZOJ 1760 How Many Shortest Path (网络流.水)
- ZOJ 2760 - How Many Shortest Path(最短路的个数) Floyd+最大流
- ZOJ 2760 How Many Shortest Path(Dijistra + ISAP 最大流)
- ZOJ 2760 How Many Shortest Path (最小费用最大流做法)
- zoj 2760 How Many Shortest Path floyd+最大流+处理的技巧
- zoj 2760 How Many Shortest Path //MAXFLOW
- zoj 2760 How Many Shortest Path
- Zoj How Many Shortest Path 2760
- ZOJ 2760 How Many Shortest Path
- ZOJ 2760 -- How Many Shortest Path
- zookeeper集群搭建
- 【DOM】3.表单校验
- JSP页面与后台交互过程的传值乱码问题解决
- Android中Serializable接口的应用
- 经典动态规划2-----Map记录
- ZOJ 2760 How Many Shortest Path 网络最大流
- 【Sonar】Sonar实战篇
- MySQL
- JSON(对象数组,HashMap)
- php版本
- RecyclerView和EditText焦点冲突和输入法软键盘把布局顶出屏幕之外的解决
- HDU-5102-The K-th Distance【思维】【好题】
- Sass mixin
- DES(ecb)加密