HDU 3416 Marriage Match IV(ISAP+最短路)题解
题意:从A走到B,有最短路,问这样不重复的最短路有几条
思路:先来讲选有效边,我们从start和end各跑一次最短路,得到dis1和dis2数组,如果dis1[u] + dis2[v] + cost[u][v] == dis1[end],那么uv这条边是最短路的一条边。然后我们选完边,把边加入ISAP,然后跑一边就行了...还没学过SAP只会敲模板....
错误思路:刚开始想的是先求出最短路,然后用费用流spfa去跑,边容量1,如果跑出一条路径费用等于最短路,那么路径+1,继续跑,但是超时了,看了半天是spfa跑费用流太慢的关系...等我学会网络流其他算法再来看这种emmm
代码:
#include<cstdio>
#include<set>
#include<cmath>
#include<stack>
#include<vector>
#include<queue>
#include<cstring>
#include<string>
#include<sstream>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn = +;
const int INF = 0x3f3f3f3f; //网络流ISAP
struct Node{
int to,next,cap,flow;
}edge[];
int tot;
int head[maxn];
int gap[maxn],dep[maxn],pre[maxn],cur[maxn];
void init(){
tot = ;
memset(head,-,sizeof(head));
}
void addEdge(int u,int v,int w,int rw = ){
edge[tot].to = v;
edge[tot].cap = w;
edge[tot].flow = ;
edge[tot].next = head[u];
head[u] = tot++; edge[tot].to = u;
edge[tot].cap = rw;
edge[tot].flow = ;
edge[tot].next = head[v];
head[v] = tot++;
}
int sap(int start,int end,int N){
memset(gap,,sizeof(gap));
memset(dep,,sizeof(dep));
memcpy(cur,head,sizeof(head));
int u = start;
pre[u] = -;
gap[u] = N;
int ans = ;
while(dep[start] < N){
if(u == end){
int Min = INF;
for(int i = pre[u];i != -;i = pre[edge[i^].to]){
if(Min > edge[i].cap - edge[i].flow){
Min = edge[i].cap - edge[i].flow;
}
}
for(int i = pre[u];i != -;i = pre[edge[i^].to]){
edge[i].flow += Min;
edge[i^].flow -= Min;
}
u = start;
ans += Min;
continue;
}
bool flag = false;
int v;
for(int i = cur[u];i != -;i = edge[i].next){
v = edge[i].to;
if(edge[i].cap- edge[i].flow && dep[v] + == dep[u]){
flag = true;
cur[u] = pre[v] = i;
break;
}
}
if(flag){
u = v;
continue;
}
int Min = N;
for(int i = head[u];i != -;i = edge[i].next){
if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min){
Min = dep[edge[i].to];
cur[u] = i;
}
}
gap[dep[u]]--;
if(!gap[dep[u]]) return ans;
dep[u] = Min + ;
gap[dep[u]]++;
if(u != start) u = edge[pre[u]^].to;
}
return ans;
} struct road{
int v,cost,next;
}e[];
int head2[maxn],tol,MinPath;
void addRoad(int u,int v,int w){
e[tol].v = v;
e[tol].cost = w;
e[tol].next = head2[u];
head2[u] = tol++;
}
bool vis1[maxn];
int cnt[maxn],dist[maxn];
bool SPFA(int st,int n){
memset(vis1,false,sizeof(vis1));
for(int i = ;i <= n;i++) dist[i] = INF;
vis1[st] = true;
dist[st] = ;
queue<int> q;
while(!q.empty()) q.pop();
q.push(st);
memset(cnt,,sizeof(cnt));
cnt[st] = ;
while(!q.empty()){
int u = q.front();
q.pop();
vis1[u] = false;
for(int i = head2[u];i != -;i = e[i].next){
int v = e[i].v;
if(dist[v] > dist[u] + e[i].cost){
dist[v] = dist[u] + e[i].cost;
if(!vis1[v]){
vis1[v] = true;
q.push(v);
if(++cnt[v] > n) return false;
}
}
}
}
return true;
}
int dis1[maxn];
int u[],v[],w[];
int main(){
int n,m,T;
scanf("%d",&T);
while(T--){
init();
scanf("%d%d",&n,&m);
for(int i = ;i < m;i++){
scanf("%d%d%d",&u[i],&v[i],&w[i]);
}
int st,en;
scanf("%d%d",&st,&en);
tol = ;
memset(head2,-,sizeof(head2));
for(int i = ;i < m;i++){
addRoad(u[i],v[i],w[i]);
}
SPFA(st,n);
MinPath = dist[en];
memcpy(dis1,dist,sizeof(dist));
tol = ;
memset(head2,-,sizeof(head2));
for(int i = ;i < m;i++){
addRoad(v[i],u[i],w[i]);
}
SPFA(en,n);
for(int i = ;i < m;i++){
if(dis1[u[i]] + dist[v[i]] + w[i] == MinPath)
addEdge(u[i],v[i],);
}
int flow = sap(st,en,n);
printf("%d\n",flow);
}
return ;
}
HDU 3416 Marriage Match IV(ISAP+最短路)题解的更多相关文章
- 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 【最短路】(记录路径)+【最大流】
<题目链接> 题目大意: 给你一张图,问你其中没有边重合的最短路径有多少条. 解题分析: 建图的时候记得存一下链式后向边,方便寻找最短路径,然后用Dijkstra或者SPFA跑一遍最短路, ...
- HDU 3416 Marriage Match IV(最短路,网络流)
题面 Do not sincere non-interference. Like that show, now starvae also take part in a show, but it tak ...
- hdu 3416 Marriage Match IV 【 最短路 最大流 】
求边不可重复的最短路条数 先从起点到终点用一次dijkstra,再从终点到起点用一次dijkstra,来判断一条边是否在最短路上 如果在,就将这条边的两个端点连起来,容量为1 再跑一下dinic(), ...
- 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 (最短路建图+最大流)
(点击此处查看原题) 题目分析 题意:给出一个有n个结点,m条单向边的有向图,问从源点s到汇点t的不重合的最短路有多少条,所谓不重复,意思是任意两条最短路径都不共用一条边,而且任意两点之间的边只会用一 ...
- HDU 3416 Marriage Match IV dij+dinic
题意:给你n个点,m条边的图(有向图,记住一定是有向图),给定起点和终点,问你从起点到终点有几条不同的最短路 分析:不同的最短路,即一条边也不能相同,然后刚开始我的想法是找到一条删一条,然后光荣TLE ...
- HDU 3416 Marriage Match IV
最短路+最大流 #include<cstdio> #include<cstring> #include<string> #include<cmath> ...
随机推荐
- 【黑金ZYNQ7000系列原创视频教程】06.ZYNQ来自FPGA的中断——按键中断实验
黑金论坛地址: http://www.heijin.org/forum.php?mod=viewthread&tid=36640&extra=page%3D1 爱奇艺地址: http: ...
- 神奇的随机数rand()
随机数在统计理论中占有很重要的地位,很多应用都需要用到他,系统自带的rand()函数产生的是伪随机数,所以该如何真正的随机数呢? 1.c语言中的时间函数 关于c语言我查到的两个比较好的博文是:http ...
- 【JavaScript算法】---快速排序法
一.快速排序法概念 我们将一个杂乱无章的数组进行一个快速排序,可以先从一个数组中取一个中间值,将一个数组一分为2,左边的数组跟中间值进行比较,小的放在左边,大的放在右边.比较完毕后再次取中间值,再次比 ...
- Flum入门必备知识
1.flume概念 flume是分布式的,可靠的,高可用的,用于对不同来源的大量的日志数据进行有效收集.聚集和移动,并以集中式的数据存储的系统. flume目前是apache的一个顶级项目. flum ...
- opencv学习笔记——图像缩放函数resize
opencv提供了一种图像缩放函数 功能:实现对输入图像缩放到指定大小 函数原型: void cv::resize ( InputArray src, OutputArray dst, Size ds ...
- Javascript计算星座
今天看群里一哥们折腾得挺热乎,手痒随便写了一个DEMO,供初学者参考. 重点,写程序先定注释,明确思路后再写具体代码. //星座定义 var constellations = [ {"Sta ...
- Oracle等待事件之db file sequential read/ db file parallel read
1.产生原因 db file sequential read这个是非常常见的I/O 相关的等待事件.表示发生了与索引扫描相关的等待.意味着I/O 出现了问题,通常表示I/O竞争或者I/O 需求太多. ...
- UVA 624 ---CD 01背包路径输出
DescriptionCD You have a long drive by car ahead. You have a tape recorder, but unfortunately your b ...
- 商铺项目(Redis缓存)
AOF,RDB是两种 redis持久化的机制.用于crash后,redis的恢复. 两种区别就是,AOF是持续的用日志记录写操作,crash后利用日志恢复:RDB是平时写操作的时候不触发写,只有手动提 ...
- rtcp多媒体控制协议应用
rtcp package send/recv demo main.c #include <stdio.h> #include <rtp.h> #include <rtcp ...