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> ...
随机推荐
- Hibernate(1)——数据访问层的架构模式<转>
数据库的概念.逻辑.数据模型概念 应用程序的分层体系结构发展 MVC设计模式与四层结构的对应关系 持久层的设计目标 数据映射器架构模式 JDBC的缺点 Hibernate简介 迅速使用Hibernat ...
- dubbo有什么作用
转自:http://blog.csdn.net/ichsonx/article/details/39008519 1. Dubbo是什么? Dubbo是一个分布式服务框架,致力于提供高性能和透明化的R ...
- Swift - 多线程GCD详解
// GCD详解 // 目录: // 1. 创建GCD队列(最常用) // 2. 自定义创建队列 // 3. 使用多线程实现延迟加载 // 4. 使用多线程实现重复(循环) // 5. ...
- Scala 泛型类型和方法
abstract class Stack[A] { def push(x: A): Stack[A] = new NonEmptyStack[A](x, this) def isEmpty: Bool ...
- Sublime 取消每次自动更新弹窗设置
首选项 --> 设置-用户(英文版 : "Preferences - -> "Settings - user"") update_check ...
- 焦作网络赛B-Mathematical Curse【dp】
A prince of the Science Continent was imprisoned in a castle because of his contempt for mathematics ...
- SQLite随机获取一行数据
Mysql中随机获取一行数据: SELECT * FROM table ORDER BY RAND() limit 1 SQLite中随机获取一行数据: SELECT * FROM table ORD ...
- I/O排查命令
I/O可以说是问题大户,线上的问题经常都是它引起的,很多人却不知道怎么定位这种问题.今天简单介绍一下,在此抛砖引玉. 此类问题我们一般分三步定位:按系统级I/O.进程级I/O.业务级I/O定位即可,一 ...
- Scala并发编程模型AKKA
一.并发编程模型AKKA Spark使用底层通信框架AKKA 分布式 master worker hadoop使用的是rpc 1)akka简介 写并发程序很难,AKKA解决spark这个问题. akk ...
- 从零开始写JavaWeb框架(第一章节)
买了本<从零开始写JavaWeb框架> 因为是第一次用IDEA,期间遇到很多问题,比如:怎么在IDEA中配置tomcat: 在IDEA界面的右上角点击: 点击+,选择Maven 到了如下界 ...