HDU-3416 Marriage Match IV 最短路+最大流 找各最短路的所有边
题目链接:https://cn.vjudge.net/problem/HDU-3416
题意
给一个图,求AB间最短路的条数(每一条最短路没有重边。可有重复节点)
思路
首先把全部最短路的边找出来,再来一遍最大流
所以如何找到全部最短路的边就是一个问题了
首先求从A到B的各节点最短路,再求B到A的最短路(注意把边反向)
便利所有边,如果满足distA[from]+distB[to]+dist==distA[B],那么这个边{from, to, dist}就是最短路中的一个边
然后最大流即可
提交过程
| TLE1 | 纯属胡写,给了最小费用最大流的代码 |
| TLE2 | 胡写2,给代码加了个判断,总是求最短路的最大流 |
| TLE3 | 思路正确,然而超时,应该是EdmondsKarp超时 |
| TLE4 | Bellman栈优化,超时原因同上 |
| TLE5 | EdmondsKarp换SAP,超时原因可能是maxn和maxm给少了 |
| TLE6 | 怀疑Bellman栈优化有问题,换回队列 |
| MLE7 | maxn和maxm给多了 |
| AC | maxn和maxm按原题乘以2 |
| TLE7 | 怀疑EdmondsKarp超时,于是试了试,果然如此 |
代码
#include <stack>
#include <queue>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=2e3+10, maxm=2e5+10, INF=0x3f3f3f3f;
struct Edge{
int to, dis, next;
Edge(int to=0, int dis=0, int next=0):
to(to), dis(dis), next(next) {}
}edges[maxm+5];
struct FlowEdge{
int from, to, cap, flow, next;
FlowEdge(int from=0, int to=0, int cap=0, int next=0):
from(from), to(to), cap(cap), next(next) {}
}fedges[maxm+5];
int head[maxn+5], fhead[maxn+5], esize, fsize, dis[2][maxn+5];
void init(void){
memset(head, -1, sizeof(head));
esize=0;
}
void addEdge(int from, int to, int dis){
edges[esize]=Edge(to, dis, head[from]);
head[from]=esize++;
}
bool Bellman(int st, int n, int which){
bool inq[maxn+5]={false};
int cnt[maxn+5]={0}, dist[maxn+5];
queue<int> que; // stack<int> sta;
memset(dist, INF, sizeof(dist));
dist[st]=0; inq[st]=true; cnt[st]=1;
que.push(st); // sta.push(st);
while (que.size()){
int from=que.front(); que.pop();
inq[from]=false;
for (int i=head[from]; i!=-1; i=edges[i].next){
Edge &e=edges[i];
int &to=e.to;
if (dist[to]<=dist[from]+e.dis) continue;
dist[to]=dist[from]+e.dis;
if (inq[to]) continue;
inq[to]=true; que.push(to);
if (++cnt[to]>n) return false;
}
}
memcpy(dis[which], dist, sizeof(dist));
return true;
}
void finit(void){
memset(fhead, -1, sizeof(fhead));
fsize=0;
}
void addFlowEdge(int from, int to, int cap){
fedges[fsize]=FlowEdge(from, to, cap, fhead[from]);
fhead[from]=fsize++;
fedges[fsize]=FlowEdge(to, from, 0, fhead[to]);
fhead[to]=fsize++;
}
int d[maxn+5], pre[maxn+5], gap[maxn+5], cur[maxn+5];
int sap(int start,int end,int nodenum){
memset(d,0,sizeof(d));
memset(gap,0,sizeof(gap));
memcpy(cur,fhead,sizeof(fhead));
int u=pre[start]=start,maxflow=0,aug=-1;
gap[0]=nodenum;
while(d[start]<nodenum){
loop:
for(int &i=cur[u];i!=-1;i=fedges[i].next){
int v=fedges[i].to;
if(fedges[i].cap&&d[u]==d[v]+1){
if(aug==-1||aug>fedges[i].cap)
aug=fedges[i].cap;
pre[v]=u;
u=v;
if(v==end){
maxflow+=aug;
for(u=pre[u];v!=start;v=u,u=pre[u]){
fedges[cur[u]].cap-=aug;
fedges[cur[u]^1].cap+=aug;
}
aug=-1;
}
goto loop;
}
}
int mind=nodenum;
for(int i=fhead[u]; i!=-1; i=fedges[i].next){
int v=fedges[i].to;
if(fedges[i].cap && mind>d[v]){
cur[u]=i;
mind=d[v];
}
}
if((--gap[d[u]])==0) break;
gap[d[u]=mind+1]++;
u=pre[u];
}
return maxflow;
}
int main(void){
int T, n, m;
int from[maxm+5], to[maxm+5], di[maxm+5], st, tar;
scanf("%d", &T);
while (T--){
scanf("%d%d", &n, &m);
init();
for (int i=0; i<m; i++){
scanf("%d%d%d", &from[i], &to[i], &di[i]);
addEdge(from[i], to[i], di[i]);
}scanf("%d%d", &st, &tar);
Bellman(st, n, 0);
init();
for (int i=0; i<m; i++)
addEdge(to[i], from[i], di[i]);
Bellman(tar, n, 1);
finit();
for (int i=0; i<m; i++)
if (to[i]!=from[i] && dis[0][from[i]]+dis[1][to[i]]+di[i]==dis[0][tar])
addFlowEdge(from[i], to[i], 1);
printf("%d\n", sap(st, tar, n));
}
return 0;
}
| Time | Memory | Length | Lang | Submitted |
|---|---|---|---|---|
| 140ms | 10332kB | 3727 | G++ | 2018-06-09 00:24:00 |
HDU-3416 Marriage Match IV 最短路+最大流 找各最短路的所有边的更多相关文章
- HDU 3416 Marriage Match IV (最短路径&&最大流)
/*题意: 有 n 个城市,知道了起点和终点,有 m 条有向边,问从起点到终点的最短路一共有多少条.这是一个有向图,建边的时候要注意!!解题思路:这题的关键就是找到哪些边可以构成最短路,其实之前做最短 ...
- HDU 3416 Marriage Match IV (Dijkstra+最大流)
题意:N个点M条边的有向图,给定起点S和终点T,求每条边都不重复的S-->T的最短路有多少条. 分析:首先第一步需要找出所有可能最短路上的边.怎么高效地求出呢?可以这样:先对起点S,跑出最短路: ...
- hdu 3416 Marriage Match IV (最短路+最大流)
hdu 3416 Marriage Match IV Description Do not sincere non-interference. Like that show, now starvae ...
- HDU 3416 Marriage Match IV (最短路径,网络流,最大流)
HDU 3416 Marriage Match IV (最短路径,网络流,最大流) Description Do not sincere non-interference. Like that sho ...
- HDU 3416 Marriage Match IV (求最短路的条数,最大流)
Marriage Match IV 题目链接: http://acm.hust.edu.cn/vjudge/contest/122685#problem/Q Description Do not si ...
- HDU 3416 Marriage Match IV dij+dinic
题意:给你n个点,m条边的图(有向图,记住一定是有向图),给定起点和终点,问你从起点到终点有几条不同的最短路 分析:不同的最短路,即一条边也不能相同,然后刚开始我的想法是找到一条删一条,然后光荣TLE ...
- HDU 3416 Marriage Match IV
最短路+最大流 #include<cstdio> #include<cstring> #include<string> #include<cmath> ...
- HDU 3416 Marriage Match IV 【最短路】(记录路径)+【最大流】
<题目链接> 题目大意: 给你一张图,问你其中没有边重合的最短路径有多少条. 解题分析: 建图的时候记得存一下链式后向边,方便寻找最短路径,然后用Dijkstra或者SPFA跑一遍最短路, ...
- HDU 3416 Marriage Match IV(ISAP+最短路)题解
题意:从A走到B,有最短路,问这样不重复的最短路有几条 思路:先来讲选有效边,我们从start和end各跑一次最短路,得到dis1和dis2数组,如果dis1[u] + dis2[v] + cost[ ...
- HDU 3416 Marriage Match IV (最短路建图+最大流)
(点击此处查看原题) 题目分析 题意:给出一个有n个结点,m条单向边的有向图,问从源点s到汇点t的不重合的最短路有多少条,所谓不重复,意思是任意两条最短路径都不共用一条边,而且任意两点之间的边只会用一 ...
随机推荐
- 苹果操作系统名称演变史 新名称macOS
历史回顾 发布年代 名称 序号 1994-1999 Classic Mac OS 1-9 2001-2011 Mac OS X 10.0-Lion 2012-2015 OS X Mountain Li ...
- spring使用注解开发
1.准备工作(1)导入common-annotations.jar(2)导入schema文件 文件名为spring-context-2.5.xsd(3)在xml的beans节点中配置 service层 ...
- laravel 常用单词翻译
1.ORM:(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping), 翻译为:对象关系映射. 是一种程序技术,用于实现面向对象编程语言里不同类型系统的 ...
- linux下wps的字体缺失解决方法
可以参考Mr.Liang 说明:当安装好wps for linux,然后打开wps会提示字体缺失,可做如下操作: 1.下载wps缺失字体(资源侵权联系我删除) 2.解压 unzip -d ./wps_ ...
- Python 绘图与可视化 matplotlib(下)
详细的参考链接:更详细的:https://www.cnblogs.com/zhizhan/p/5615947.html 图像.子图.坐标轴以及记号 Matplotlib中图像的意思是打开的整个画图窗口 ...
- 记一次BootStrap的使用
效果图如下: 一.简介: 什么是Bootstrap? Bootstrap 是一个用于快速开发 Web 应用程序和网站的前端框架. 什么是响应式布局? 引用一句Bootstrap的标题语 “Boots ...
- java拷贝字符文件
1.java拷贝字符文件 2.代码如下: package Demo1; import java.io.*; public class copyfile { public static void mai ...
- 2015 Multi-University Training Contest 8 hdu 5389 Zero Escape
Zero Escape Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Tot ...
- C/C++ 名正则言顺
本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/50532701 名称所表达的含义极其丰富 ...
- Collection、List、Set、Map之间的关系
初学java,单个的接触有点迷糊,所以总结下他们的关系 一.关系 Collection --List:以特定顺序存储 --ArrayList.LinkList.Vector --Set:不能包含重复的 ...