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> ...
随机推荐
- LeetCode——Generate Parentheses
Description: Given n pairs of parentheses, write a function to generate all combinations of well-for ...
- Excel 2010 最熟悉的陌生功能:筛选器(将当前所选内容添加到筛选器)
使用excel2010版的同学,在进行筛选时,肯定都对这句话很熟悉:将当前所选内容添加到筛选器.但很多同学天天看到,却不知道什么是筛选器?它有什么作用. 其实,这里所指的筛选器就是储存筛选结果的一个虚 ...
- ts和js中let和var定义变量的区别
javascript 严格模式 第一次接触let关键字,有一个要非常非常要注意的概念就是”JavaScript 严格模式”,比如下述的代码运行就会报错: let hello = 'hello worl ...
- C# DateTime.Now详细用法
//2008年4月24日 System.DateTime.Now.ToString("D"); //2008-4-24 System.DateTime.Now.ToString(& ...
- Javaweb程序打包或exe执行文件
java程序的打包与发布 这里主要是讲解一下怎样将 Java程序打包成独立运行的exe程序包,以下这种方法应该是最佳的解决方案了.NetDuke的EXE程序包了是使用这种方案制作的.在操作步骤上还是比 ...
- oracle 日期常用函数(转载)
日期运算函數 ADD_MONTHS(d,n) --时间点d再加上n个月 ex. select sysdate, add_months(sysdate,2) aa f ...
- JavaScript三(对象思想)
JavaScript并不是面向对象的程序设计语言,但它是基于对象的.JavaScript中的每个函数都可用于创建对象,返回的对象既是该对象的实例,也是object的实例 . 一.对象与关联数组 Jav ...
- 常用linq语法
1.简单的linq语法 var ss = from r in db.Am_recProScheme select r; var ss1 = db.Am_recProScheme; string sss ...
- HOJ 1936&POJ 2955 Brackets(区间DP)
Brackets My Tags (Edit) Source : Stanford ACM Programming Contest 2004 Time limit : 1 sec Memory lim ...
- sosi-statistics
set echo offset scan onset lines 150set pages 66set verify offset feedback offset termout offcolumn ...