人老了就比较懒,故意挑了到看起来很和蔼的题目做,然后套个spfa和dinic的模板WA了5发,人老了,可能不适合这种刺激的竞技运动了……

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2760

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

4
0 1 1 -1
-1 0 1 1
-1 -1 0 1
-1 -1 -1 0
0 3
5
0 1 1 -1 -1
-1 0 1 1 -1
-1 -1 0 1 -1
-1 -1 -1 0 1
-1 -1 -1 -1 0
0 4

Sample Output

2
1

呃,题意和思路什么的直接看宝典吧:

当然啦,没必要一定像他那样ds[i]+edge[i][j]+dt[j]==ds[t]这样,我们要抓住精髓,看清本质,只要保证剌进来的边属于最短路上的边就行,

所以,只要做一次spfa,然后满足d[i]+edge[i][j]==d[j]就行。

某只A题A的神志不清的博主的心灵独白                                                                   begin

然后联想到前面那题POJ1637的构图,不难发现,在integer的情况下把edge.cap设为1,可以代表一种这条边到底走不走的意义,然后全图都设为1的话,最大流大概就是……

从source到target最多有几条不相交的简单路径可走……

嗯,如果这个图上的边全是属于最短路的边的话,那么这个最大流就是本题的答案了……诶等下,再联想到dinic的BFS过程是找层次图,而层次图从某种意义上来讲就是最短路图?

所以我们可以用一个计算层次的BFS来代替SPFA?我好想发现了什么??让我来再码一发(然而spfa本来不就是个BFS么……

然后,我立马就发现……dinic里的BFS是建立在边长默认为1的情况下的,所以我立马就放弃了我TM真是个傻子……

某只A题A的神志不清的博主的心灵独白                                                                   end

呃,先忽略我的心灵独白,看跟现在市面上比较相像的代码:

 #include<cstdio>
#include<cstring>
#include<queue>
#define MAXN 103
#define INF 0x3f3f3f3f
using namespace std;
int n,s,t;
int d[MAXN],map[MAXN][MAXN];
bool vis[MAXN];
void spfa(int st)
{
for(int i=;i<n;i++){
i==st ? d[i]= : d[i]=INF;
vis[i]=;
}
queue<int> q;
q.push(st);
vis[st]=;
while(!q.empty())
{
int u=q.front();q.pop();vis[u]=;
for(int v=;v<n;v++)
{
if(u==v || map[u][v]==-) continue;
int tmp=d[v];
if(d[v]>d[u]+map[u][v]) d[v]=d[u]+map[u][v];
if(d[v]<tmp && !vis[v]) q.push(v),vis[v]=;
}
}
} struct Edge{
int u,v,c,f;
};
struct Dinic
{
vector<Edge> E;
vector<int> G[MAXN];
bool vis[MAXN]; //BFS使用
int lev[MAXN];//记录层次
int cur[MAXN]; //当前弧下标
void init(int n)
{
E.clear();
for(int i=;i<n;i++) G[i].clear();
}
void addedge(int from,int to,int cap)
{
E.push_back((Edge){from,to,cap,});
E.push_back((Edge){to,from,,});
int m=E.size();
G[from].push_back(m-);
G[to].push_back(m-);
}
bool bfs()
{
memset(vis,,sizeof(vis));
queue<int> q;
q.push(s);
lev[s]=;
vis[s]=;
while(!q.empty())
{
int now=q.front(); q.pop();
for(int i=;i<G[now].size();i++)
{
Edge edge=E[G[now][i]];
int nex=edge.v;
if(!vis[nex] && edge.c>edge.f)//属于残存网络的边
{
lev[nex]=lev[now]+;
q.push(nex);
vis[nex]=;
}
}
}
return vis[t];
}
int dfs(int now,int aug)//now表示当前结点,aug表示目前为止的最小残量
{
if(now==t || aug==) return aug;//aug等于0时及时退出,此时相当于断路了
int flow=,f;
for(int& i=cur[now];i<G[now].size();i++)//从上次考虑的弧开始,注意要使用引用,同时修改cur[now]
{
Edge& edge=E[G[now][i]];
int nex=edge.v;
if(lev[now]+ == lev[nex] && (f=dfs(nex,min(aug,edge.c-edge.f)))>)
{
edge.f+=f;
E[G[now][i]^].f-=f;
flow+=f;
aug-=f;
if(!aug) break;//aug等于0及时退出,当aug!=0,说明当前节点还存在另一个增广路分支
}
}
return flow;
}
int maxflow()//主过程
{
int flow=;
while(bfs())//不停地用bfs构造分层网络,然后用dfs沿着阻塞流增广
{
memset(cur,,sizeof(cur));
flow+=dfs(s,INF);
}
return flow;
}
}dinic; int main()
{
while(scanf("%d",&n)!=EOF)
{
for(int i=;i<n;i++) for(int j=;j<n;j++) scanf("%d",&map[i][j]);
scanf("%d%d",&s,&t);
if(s==t)
{
printf("inf\n");
continue;
}
spfa(s);
dinic.init(n);
for(int i=;i<n;i++)
for(int j=;j<n;j++)
if(i!=j && map[i][j]!=- && d[i]!=INF && d[j]!=INF && d[i]+map[i][j]==d[j]) dinic.addedge(i,j,);
printf("%d\n",dinic.maxflow());
}
}

(dinic模板的中文注释懒得去掉了,反正看起来不多,到时候忘记了过程还可以看看注释回忆回忆……)

ZOJ 2760 - How Many Shortest Path - [spfa最短路][最大流建图]的更多相关文章

  1. ZOJ 2760 How Many Shortest Path(Dijistra + ISAP 最大流)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1760 题意:给定一个带权有向图 G=(V, E)和源点 s.汇点 t ...

  2. zoj 2760 How Many Shortest Path 最大流

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1760 Given a weighted directed graph ...

  3. ZOJ 2760 How Many Shortest Path(最短路径+最大流)

    Description Given a weighted directed graph, we define the shortest path as the path who has the sma ...

  4. zoj 2760 How Many Shortest Path【最大流】

    不重叠最短路计数. 先弗洛伊德求一遍两两距离(其实spfa或者迪杰斯特拉会更快但是没必要懒得写),然后设dis为st最短距离,把满足a[s][u]+b[u][v]+a[v][t]==dis的边(u,v ...

  5. ZOJ 2760 How Many Shortest Path (不相交的最短路径个数)

    [题意]给定一个N(N<=100)个节点的有向图,求不相交的最短路径个数(两条路径没有公共边). [思路]先用Floyd求出最短路,把最短路上的边加到网络流中,这样就保证了从s->t的一个 ...

  6. ZOJ 2760 How Many Shortest Path

    题目大意:给定一个带权有向图G=(V, E)和源点s.汇点t,问s-t边不相交最短路最多有几条.(1 <= N <= 100) 题解:从源点汇点各跑一次Dij,然后对于每一条边(u,v)如 ...

  7. HDU - 3631 Shortest Path(Floyd最短路)

    Shortest Path Time Limit: 1000MS Memory Limit: 32768KB 64bit IO Format: %I64d & %I64u SubmitStat ...

  8. CF843D Dynamic Shortest Path spfa+剪枝

    考试的T3,拿暴力+剪枝卡过去了. 没想到 CF 上也能过 ~ code: #include <bits/stdc++.h> #define N 100004 #define LL lon ...

  9. ZOJ 3781 - Paint the Grid Reloaded - [DFS连通块缩点建图+BFS求深度][第11届浙江省赛F题]

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3781 Time Limit: 2 Seconds      Me ...

随机推荐

  1. iOS 将Excel导入到SQLite3的过程

    1.打开Excel表格,另存为.csv文件 2.打开SQLite3,选择File -> Import -> other... 3.在弹出的文件选择框中选择步骤1保存的.cvs文件 4在弹出 ...

  2. 【译】调优Apache Kafka集群

    今天带来一篇译文“调优Apache Kafka集群”,里面有一些观点并无太多新颖之处,但总结得还算详细.该文从四个不同的目标出发给出了各自不同的参数配置,值得大家一读~ 原文地址请参考:https:/ ...

  3. Elasticsearch 5.x 关于term query和match query的认识

    http://blog.csdn.net/yangwenbo214/article/details/54142786 一.基本情况 前言:term query和match query牵扯的东西比较多, ...

  4. C++ template —— 模板特化(五)

    本篇讲解模板特化-------------------------------------------------------------------------------------------- ...

  5. 基于Cocos2d-x学习OpenGL ES 2.0系列——编写自己的shader(2)

    在上篇文章中,我给大家介绍了如何在Cocos2d-x里面绘制一个三角形,当时我们使用的是Cocos2d-x引擎自带的shader和一些辅助函数.在本文中,我将演示一下如何编写自己的shader,同时, ...

  6. 32位win7+vs2008编译mysql 5.6.22源码并安装

    以下这部分安装说明是来自http://www.2cto.com/database/201407/316681.html的win7+vs2010源码编译mysql,文章最后会说明用vs2008编译遇见的 ...

  7. 虚拟机可以ping同宿主机,宿主机ping不通虚拟机

    虚拟机里能ping同本机,而本机却ping不通虚拟机,或者虚拟机不能ping通本机,可能有如下原因: 如果是桥接模式,那么可能性1:虚拟机防火墙禁ping,请关闭虚拟机防火墙重试:root 状态下se ...

  8. 【node.js】】MSBUILD : error MSB3428: 未能加载 Visual C++ 组件“VCBuild.exe”。

    错误原因:缺少windows构建插件 解决方法: # (全局安装windows构建工具) npm install --global --production windows-build-tools

  9. Geoserver

    Geoserver是一个功能齐全,遵循OGC开放标准的开源WFS-T和WMS服务器.利用Geoserver可以把数据作为maps/images来发布(利用WMS来实现)也可以直接发布实际的数据(利用W ...

  10. springbatch---->springbatch的使用(三)

    这里我们对上篇博客的例子做一个修改性的测试来学习一下springbatch的一些关于chunk的一些有用的特性.我渐渐能意会到,深刻并不等于接近事实. springbatch的学习 一.chunk的s ...