http://acm.hdu.edu.cn/showproblem.php?pid=3416

题意:给出n个点m条边,边信息分别是两个端点和一个费用,再给出一个起点和一个终点,问从起点到终点的完全不相同的最短路径有多少条。(即走过的边不能在走过了)。

思路:因为是在网络流专题里面,所以一开始以为先用SPFA跑一个最小费用出来,然后再用最小费用最大流(然而是最小费用最大流是满足最大流的前提下再考虑最小费用的,很明显是行不通的)。后来想要保证路径不重复,就跑完一次最短路就删除路径(好像也是行不通)。然后只能看下题解了= =。

从起点到终点跑一次SPFA,再从终点到起点跑一次SPFA,这里第一次SPFA跑出来的距离数组是d[0],第二次跑出来的是d[1],如果d[0][u] + w(u, v) + d[1][v] == d[0][T],那么这条w(u,v)边一定是最短路上的边。这里说说我对这个定理的看法:d[0][u]是从起点到u点的最短距离,而d[1][v]是从v到终点的最短距离,那么如果加上这条边刚好等于从起点到终点的最短距离,那么这条边就必定是最短路的边,嗯。好像很明显。然后将这些必定在最短路上的边建起网络,容量是1,跑一遍从起点到终点的最大流,就是最终答案了。这样就符合最大流的思想了。

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
#define N 1010
#define M 200010
#define INF 0x3f3f3f3f
struct Edge {
int v, cap, nxt;
Edge () {}
Edge (int v, int nxt, int cap) : v(v), nxt(nxt), cap(cap) {}
} edge[M], e[M];
int cur[N], pre[N], gap[N], dis[N], d[][N], vis[N], head[N], h[N], uu[M], vv[M], ww[M], tot, tt, S, T, n, m; void Add(int u, int v, int cap, int tag) {
if(tag == ) { e[tt] = Edge(v, h[u], cap); h[u] = tt++; }
else { edge[tot] = Edge(v, head[u], cap); head[u] = tot++; edge[tot] = Edge(u, head[v], ); head[v] = tot++; }
} void SPFA(int st, int ed, int id) {
for(int i = ; i <= n; i++) d[id][i] = INF;
memset(vis, , sizeof(vis));
queue<int> que; que.push(st);
vis[st] = ; d[id][st] = ;
while(!que.empty()) {
int u = que.front(); que.pop(); vis[u] = ;
for(int i = h[u]; ~i; i = e[i].nxt) {
int v = e[i].v, w = e[i].cap;
if(d[id][v] > d[id][u] + w) {
d[id][v] = d[id][u] + w;
if(vis[v]) continue;
que.push(v); vis[v] = ;
}
}
}
} void BFS() {
memset(dis, INF, sizeof(dis));
memset(gap, , sizeof(gap));
queue<int> que; que.push(T);
dis[T] = ; gap[]++;
while(!que.empty()) {
int u = que.front(); que.pop();
for(int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].v;
if(dis[v] != INF) continue;
dis[v] = dis[u] + ;
gap[dis[v]]++;
que.push(v);
}
}
} int ISAP(int n) {
BFS();
memcpy(cur, head, sizeof(cur));
int u = pre[S] = S, ans = , flow, i, index;
while(dis[S] < n) {
if(u == T) {
flow = INF;
for(i = S; i != T; i = edge[cur[i]].v)
if(flow > edge[cur[i]].cap) flow = edge[cur[i]].cap, index = i;
for(i = S; i != T; i = edge[cur[i]].v)
edge[cur[i]].cap -= flow, edge[cur[i]^].cap += flow;
u = index; ans += flow;
}
for(i = cur[u]; ~i; i = edge[i].nxt) if(edge[i].cap > && dis[edge[i].v] + == dis[u]) break;
if(~i) { cur[u] = i; pre[edge[i].v] = u; u = edge[i].v; }
else {
if(--gap[dis[u]] == ) break;
int md = n + ;
for(i = head[u]; ~i; i = edge[i].nxt)
if(dis[edge[i].v] < md && edge[i].cap > ) md = dis[edge[i].v], cur[u] = i;
gap[dis[u] = md + ]++;
u = pre[u];
}
}
return ans;
} int main() {
int t;
scanf("%d", &t);
while(t--) {
scanf("%d%d", &n, &m);
int edgenum = ;
for(int i = ; i <= m; i++) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
//if(u == v) continue;
edgenum++; uu[edgenum] = u; vv[edgenum] = v; ww[edgenum] = w;
}
scanf("%d%d", &S, &T);
memset(h, -, sizeof(h)); tt = ;
for(int i = ; i <= edgenum; i++) Add(uu[i], vv[i], ww[i], );
SPFA(S, T, );
memset(h, -, sizeof(h)); tt = ;
for(int i = ; i <= edgenum; i++) Add(vv[i], uu[i], ww[i], );
SPFA(T, S, );
memset(head, -, sizeof(head)); tot = ;
for(int i = ; i <= edgenum; i++)
if(d[][uu[i]] + d[][vv[i]] + ww[i] == d[][T]) Add(uu[i], vv[i], , ); // 容量设成1.而不是ww
int ans = ISAP(n + );
printf("%d\n", ans);
}
return ;
}

HDU 3416:Marriage Match IV(最短路+最大流)的更多相关文章

  1. HDU 3416 Marriage Match IV (最短路建图+最大流)

    (点击此处查看原题) 题目分析 题意:给出一个有n个结点,m条单向边的有向图,问从源点s到汇点t的不重合的最短路有多少条,所谓不重复,意思是任意两条最短路径都不共用一条边,而且任意两点之间的边只会用一 ...

  2. HDU 3416 Marriage Match IV (Dijkstra+最大流)

    题意:N个点M条边的有向图,给定起点S和终点T,求每条边都不重复的S-->T的最短路有多少条. 分析:首先第一步需要找出所有可能最短路上的边.怎么高效地求出呢?可以这样:先对起点S,跑出最短路: ...

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

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

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

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

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

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

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

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

  7. HDU 3416 Marriage Match IV

    最短路+最大流 #include<cstdio> #include<cstring> #include<string> #include<cmath> ...

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

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

  9. HDU 3416 Marriage Match IV(ISAP+最短路)题解

    题意:从A走到B,有最短路,问这样不重复的最短路有几条 思路:先来讲选有效边,我们从start和end各跑一次最短路,得到dis1和dis2数组,如果dis1[u] + dis2[v] + cost[ ...

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

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

随机推荐

  1. 在Keystone V3基础上改进的分布式认证体系

    目标 使用java实现keystone v3相关功能与概念: api client authentication service discovery distributed multi-tenant ...

  2. Angular语法(三)——数据绑定

    绑定类型 绑定类型可以按照数据流的方向分为三类:从源到视图,从视图到源,以及双向序列 示例 <!-- Bind button disabled state to `isUnchanged` pr ...

  3. WPF DataGrid自定义列DataGridTextColumn.ElementStyle和DataGridTemplateColumn.CellTemplate

    <Window x:Class="DataGridExam.MainWindow"        xmlns="http://schemas.microsoft.c ...

  4. Delphi中返回类型为string的函数的一个陷阱(不是很懂)

    如果类的一个成员函数的返回值是string类型,需要注意一个问题 其返回值可能是错误的 例如函数的实现如下 function GetString( s: string ): string;begin  ...

  5. 动态lambda 构建

    var param = Expression.Parameter(typeof(T)); var datetime1 = Expression.Constant(dt1); var datetime2 ...

  6. Debian下编译安装驱动模块

    在Linux下,我们常有需要自己来编译安装驱动模块的情况,例如要安装显卡驱动,要安装无线驱动,有的时候某个程序的安装使用与需要安装相应的驱动模块.Debian Linux下的生活本已十分简单,使用ap ...

  7. Win8 Metro(C#)数字图像处理--2.72图像噪声

    原文:Win8 Metro(C#)数字图像处理--2.72图像噪声  [函数名称]   噪声函数WriteableBitmap NoiseProcess(WriteableBitmap src,  ...

  8. GIS基础软件及操作(十二)

    原文 GIS基础软件及操作(十二) 练习十二. ArcMap制图-地图版面设计 设置地图符号-各种渲染方式的使用 使用ArcMap Layout(布局)界面制作专题地图 将各种地图元素添加到地图版面中 ...

  9. Android零基础入门第19节:Button使用详解

    原文:Android零基础入门第19节:Button使用详解 Button(按钮)是Android开发中使用非常频繁的组件,主要是在UI界面上生成一个按钮,该按钮可以供用户单击,当用户单击按钮时,按钮 ...

  10. storm(二)消息的可靠处理

    storm 通过 trident保证了对消息提供不同的级别.beast effort,at least once, exactly once. 一个tuple 从spout流出,可能会导致大量的tup ...