题目传送门

题意:求A到B不同最短路的条数(即边不能重复走, 点可以多次走)

分析:先从A跑最短路,再从B跑最短路,如果d(A -> u) + w (u, v) + d (B -> v) == shortest path,那么这条边就是有用边(在最短路中),利用这个性质重新建最大流的图,然后增广路算法Dinic求出最多有多少条最短路.SPFA + Dinic 组合已经见过一次了

#include <bits/stdc++.h>
using namespace std; const int N = 1e3 + 5;
const int M = 1e5 + 5;
const int INF = 0x3f3f3f3f;
struct Edge {
int u, v, w, nex;
Edge() {}
Edge(int u, int v, int w, int nex) : u (u), v (v), w (w), nex (nex) {}
}edge[2][M];
struct Flow {
int v, cap, rev;
Flow() {}
Flow(int v, int cap, int rev) : v (v), cap (cap), rev (rev) {}
};
vector<Flow> F[N];
int it[N];
int lv[N];
int head[2][N];
int d[2][N];
bool vis[N];
int n, m, e[2];
int a, b, sp; void init(int id) {
memset (head[id], -1, sizeof (head[id]));
e[id] = 0;
} void add_edge(int u, int v, int w, int id) {
edge[id][e[id]] = Edge (u, v, w, head[id][u]);
head[id][u] = e[id]++;
} void re_edge(void) {
init (1);
for (int i=0; i<e[0]; ++i) {
add_edge (edge[0][i].v, edge[0][i].u, edge[0][i].w, 1);
}
} void add_flow_edge(int u, int v, int cap) {
F[u].push_back (Flow (v, cap, (int) F[v].size ()));
F[v].push_back (Flow (u, 0, (int) F[u].size ()-1));
} void BFS(int s) {
memset (lv, -1, sizeof (lv));
queue<int> que; que.push (s); lv[s] = 0;
while (!que.empty ()) {
int u = que.front (); que.pop ();
for (int i=0; i<F[u].size (); ++i) {
Flow &e = F[u][i];
if (e.cap > 0 && lv[e.v] < 0) {
lv[e.v] = lv[u] + 1;
que.push (e.v);
}
}
}
} int DFS(int u, int t, int f) {
if (u == t) return f;
for (int &i=it[u]; i<F[u].size (); ++i) {
Flow &e = F[u][i];
if (e.cap > 0 && lv[u] < lv[e.v]) {
int d = DFS (e.v, t, min (f, e.cap));
if (d > 0) {
e.cap -= d; F[e.v][e.rev].cap += d;
return d;
}
}
}
return 0;
} //最大流算法
int Dinic(int s, int t) {
int flow = 0, f;
for (; ;) {
BFS (s);
if (lv[t]< 0) return flow;
memset (it, 0, sizeof (it));
while ((f = DFS (s, t, INF)) > 0) flow += f;
}
} void build_max_flow_graph(void) {
for (int i=1; i<=n; ++i) F[i].clear ();
for (int i=0; i<m; ++i) {
Edge &e = edge[0][i];
if (d[0][e.u] + e.w + d[1][e.v] == sp) {
add_flow_edge (e.u, e.v, 1);
add_flow_edge (e.v, e.u, 0);
}
}
} void SPFA(int s, int id) {
memset (d[id], INF, sizeof (d[id]));
memset (vis, false, sizeof (vis));
d[id][s] = 0; vis[s] = true;
queue<int> que; que.push (s);
while (!que.empty ()) {
int u = que.front (); que.pop ();
vis[u] = false;
for (int i=head[id][u]; ~i; i=edge[id][i].nex) {
int v = edge[id][i].v, w = edge[id][i].w;
if (d[id][v] > d[id][u] + w) {
d[id][v] = d[id][u] + w;
if (!vis[v]) {
vis[v] = true; que.push (v);
}
}
}
}
} int run(void) {
SPFA (a, 0);
sp = d[0][b];
if (sp == INF) return 0;
re_edge ();
SPFA (b, 1);
build_max_flow_graph ();
return Dinic (a, b);
} int main(void) {
int T; scanf ("%d", &T);
while (T--) {
init (0);
scanf ("%d%d", &n, &m);
for (int u, v, w, i=1; i<=m; ++i) {
scanf ("%d%d%d", &u, &v, &w);
add_edge (u, v, w, 0);
}
scanf ("%d%d", &a, &b);
printf ("%d\n", run ());
} return 0;
}

  

SPFA+Dinic HDOJ 3416 Marriage Match IV的更多相关文章

  1. HDU 3416 Marriage Match IV (最短路径,网络流,最大流)

    HDU 3416 Marriage Match IV (最短路径,网络流,最大流) Description Do not sincere non-interference. Like that sho ...

  2. hdu 3416 Marriage Match IV (最短路+最大流)

    hdu 3416 Marriage Match IV Description Do not sincere non-interference. Like that show, now starvae ...

  3. HDU 3416 Marriage Match IV (求最短路的条数,最大流)

    Marriage Match IV 题目链接: http://acm.hust.edu.cn/vjudge/contest/122685#problem/Q Description Do not si ...

  4. HDU 3416 Marriage Match IV 【最短路】(记录路径)+【最大流】

    <题目链接> 题目大意: 给你一张图,问你其中没有边重合的最短路径有多少条. 解题分析: 建图的时候记得存一下链式后向边,方便寻找最短路径,然后用Dijkstra或者SPFA跑一遍最短路, ...

  5. 【HDOJ】3416 Marriage Match IV

    先求SPSS.然后遍历每条边,检查是否为最短路径的边,如果是(dis[v]==dis[u]+w)则加入到网络流中.最后Dinic最大流. /* 3416 */ #include <iostrea ...

  6. HDU 3416 Marriage Match IV dij+dinic

    题意:给你n个点,m条边的图(有向图,记住一定是有向图),给定起点和终点,问你从起点到终点有几条不同的最短路 分析:不同的最短路,即一条边也不能相同,然后刚开始我的想法是找到一条删一条,然后光荣TLE ...

  7. (中等) HDU 3416 Marriage Match IV,SPFA+SAP。

    Description Do not sincere non-interference. Like that show, now starvae also take part in a show, b ...

  8. HDU 3416 Marriage Match IV(最短路,网络流)

    题面 Do not sincere non-interference. Like that show, now starvae also take part in a show, but it tak ...

  9. HDU 3416 Marriage Match IV (最短路径&&最大流)

    /*题意: 有 n 个城市,知道了起点和终点,有 m 条有向边,问从起点到终点的最短路一共有多少条.这是一个有向图,建边的时候要注意!!解题思路:这题的关键就是找到哪些边可以构成最短路,其实之前做最短 ...

随机推荐

  1. 基于SSH2的OA项目1.1_20161207_业务开发

    1.1建立用户的pojo模型 建立user.java package org.guangsoft.pojo; import java.util.HashSet; import java.util.Se ...

  2. CSS实现限制显示的字数,超出显示"..."

    一.背景 在实际项目中,我们常常需要对某些页面的某些特定区域显示指定数量的内容,超出的内容显示"..."来进行美化页面,那么应该怎么做呢?今天就让我们来看看如何达到这一效果. 二. ...

  3. [Java 基础] 使用java.util.zip包压缩和解压缩文件

    reference :  http://www.open-open.com/lib/view/open1381641653833.html Java API中的import java.util.zip ...

  4. vs c# int & int32

    在vs c#中,int就等价于int32, 所以通常也是使用int32 当在统计总数时,最好使用int32,int16数值范围太小,如果超出,就会变成随机数.

  5. NYOJ题目170网络的可靠性

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAs8AAANvCAIAAACte6C6AAAgAElEQVR4nOydPbLcNhOu7yaUayGOZy

  6. Spring.Net学习之简单的知识点(一)

    1.Spring.Net是一个开源的应用程序框架,可以简化开发主要功能(1)实现控制反转(IOC/DI),也就是不要直接new,依赖于接口(2)面向切面编程(AOP),就是向程序中利用委托注册事件简单 ...

  7. C语言的OOP实践(OOC)

    OOC 面向对象 C 语言编程实践 - 文章 - 伯乐在线http://blog.jobbole.com/105105/ ---硬着头皮看完了,但是感觉还是抽象有不理解的地方,感觉用C实现OOP好难啊 ...

  8. 【翻译十九】-java之执行器

    Executors In all of the previous examples, there's a close connection between the task being done by ...

  9. thinkphp分页样式

    html代码: <div class="pages">{$page}</div> css代码: .pages{ width:100.5%; text-ali ...

  10. WPF QuickStart系列之样式和模板(Style and Template)

    在WPF桌面程序中,当我们想构建一个统一的UI表现时(在不同操作系统下,显示效果一致),此时我们就需要使用到WPF中的样式和模板技术.简单来说,如果我们需要简单的给一个Button设置宽,高,Marg ...