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> ...
随机推荐
- 图论之最短路径(3)队列优化的Bellman-Ford算法(SPFA算法)
在Bellman-Ford算法中 我们可以看到大量的优化空间:如果一个点的最短路径已经确定了,那么它就不会再改变,因此不需要再处理.换句话说:我们每次只对最短路径改变了的顶点的所有出边进行操作 使用一 ...
- intellijIDEA常用快捷键以及和Eclipse快捷键的对照
CTRL + D 复制当前行到下一行 相当于eclipse中的 CTRL + SHIFT + 下 CTRL + / 单行注释和反注释 CTRL +SHIFT + / 块儿注释和反注释 CTRL ...
- Egret置于后台时,暂停游戏逻辑 (Egret 5 )
官网教程-生命周期:http://developer.egret.com/cn/2d/lifecycle 主要是在游戏置于后台时,关闭游戏逻辑.渲染逻辑和背景音乐,保证更好的用户体验. 一 Egret ...
- c# comboBox与数据库中的数据绑定
private void comBoxBinding() { SqlConnection connection = this.getConnection(); connection.Open(); S ...
- C#生成唯一码方法
一.时间戳方法 private string CreateId() { TimeSpan ts = DateTime.UtcNow - , , , , , , ); return Convert.To ...
- 310实验室 Linux 软件安装常见问题
电脑装好Linux系统后,系统默认安装软件不齐,需要自己根据自己的需要安装一些列工具软件,在linux系统中,用的最多的就是Synaptic Package Manager,什么是Synaptic?新 ...
- postgresql----IN&&EXISTS
一.IN && NOT IN WHERE expression IN (subquery) 右边圆括号内是返回一个字段的子查询结果集,左边的表达式(或字段)对查询结果每一行进行一次运算 ...
- ABP 样板开发框架系列
--ABP 官网与源码 http://www.aspnetboilerplate.com/ https://github.com/aspnetboilerplate --pdf和docx 文档 htt ...
- Asp.NET 与 WebApi 共享Session
首先新建一个.net framework 4.5.2的 web应用程序,选择WebApi基架,包括MVC与Webapi 1.在global.asax中启用Session 2.在HomeControll ...
- s3对象存储
bkstorages 模块帮助你在蓝鲸应用中使用多种文件存储服务作为后端,用于加速静态资源,管理用户上传文件. 自定静态文件 storage 如果通过修改配置文件满足不了你的需求,你随时可以通过继承 ...