(点击此处查看原题)

题目分析

题意:给出一个有n个结点,m条单向边的有向图,问从源点s到汇点t的不重合的最短路有多少条,所谓不重复,意思是任意两条最短路径都不共用一条边,而且任意两点之间的边只会用一条。

思路:没有看出是最大流的话,可能会止步于用dijkstra得到所有的所有最短路包含的边,但是无法确定最多有多少条路。

但是学过网络流的人走到这一步就会想到这里需要用最大流求解:我们将每一条最短路上的边构成新的图,这个图中的边的边权都是1,在这个由最短路中的边组成的图中,求得的s-t最大流即为我们所求的答案。

代码区

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<string>
#include<fstream>
#include<vector>
#include<stack>
#include <map>
#include <iomanip> #define bug cout << "**********" << endl
#define show(x, y) cout<<"["<<x<<","<<y<<"] "
#define LOCAL = 1;
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll mod = ;
const int Max = 1e5 + ;
const int Max2 = 1e3+; struct Edge
{
int to,next,flow;
}edge1[Max<<],edge2[Max<<],edge[Max<<]; int T, n, m, s, t;
int head1[Max2],tot1;
int head2[Max2],tot2;
int dis_s[Max2],dis_t[Max2]; //某结点距离源点和始点的最近距离
bool vis[Max2];
int head[Max2],tot;
int dis[Max]; void init()
{
memset(head1,-,sizeof(head1));tot1 = ;
memset(head2,-,sizeof(head2));tot2 = ;
memset(head,-,sizeof(head));tot = ;
memset(dis_s,inf,sizeof(dis_s));
memset(dis_t,inf,sizeof(dis_t));
} void add1(int u, int v,int dist) //原图的边
{
edge1[tot1].to = v;
edge1[tot1].flow = dist;
edge1[tot1].next = head1[u];
head1[u] = tot1++; edge2[tot2].to = u;
edge2[tot2].flow = dist;
edge2[tot2].next = head2[v];
head2[v] = tot2++;
} void add2(int u,int v,int flow) //跑最大流的图
{
edge[tot].to = v;
edge[tot].flow = flow;
edge[tot].next = head[u];
head[u] = tot++;
} void dfs_s()
{
priority_queue<pair<int,int> > q;
memset(vis,,sizeof(vis)); q.push(make_pair(,s));
dis_s[s] = ; while(!q.empty())
{
int u = q.top().second;q.pop();
if(vis[u]) continue;
vis[u] = true;
for(int i = head1[u] ;i != -;i = edge1[i].next)
{
int v = edge1[i].to;
if(!vis[v] && dis_s[v] > dis_s[u] + edge1[i].flow) //这里的flow就是边权,和网络流的图公用一个结构体
{
dis_s[v] = dis_s[u] + edge1[i].flow;
q.push(make_pair(-dis_s[v],v));
}
}
}
} void dfs_t()
{
priority_queue<pair<int,int> > q;
memset(vis,,sizeof(vis)); q.push(make_pair(,t));
dis_t[t] = ; while(!q.empty())
{
int u = q.top().second;q.pop();
if(vis[u]) continue;
vis[u] = true;
for(int i = head2[u] ;i != -;i = edge2[i].next)
{
int v = edge2[i].to;
if(!vis[v] && dis_t[v] > dis_t[u] + edge2[i].flow) //这里的flow就是边权,和网络流的图公用一个结构体
{
dis_t[v] = dis_t[u] + edge2[i].flow;
q.push(make_pair(-dis_t[v],v));
}
}
}
} bool bfs()
{
memset(dis,-,sizeof(dis));
queue<int>q;
q.push(s);dis[s] = ;
while(!q.empty())
{
int u = q.front();q.pop();
for(int i = head[u]; i != - ; i = edge[i].next)
{
int v = edge[i].to;
if(edge[i].flow > && dis[v] == -)
{
dis[v] = dis[u] + ;
if(v == t) return true;
q.push(v);
}
}
}
return false;
} int dfs(int u, int flow_in)
{
if(u == t) return flow_in;
int flow_out = ;
for(int i = head[u] ; i != -; i = edge[i].next)
{
int v= edge[i].to;
if(edge[i].flow > && dis[v] == dis[u] + )
{
int flow = dfs(v,min(flow_in,edge[i].flow));
if(flow == ) continue;
flow_in -= flow;
flow_out += flow;
edge[i].flow -= flow;
edge[i^].flow += flow;
if(flow_in == ) break;
}
}
return flow_out;
} int Dinic()
{
int sum = ;
while(bfs())
{
sum += dfs(s,inf);
}
return sum;
} int main()
{
#ifdef LOCAL
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
#endif
scanf("%d",&T);
while(T--)
{
init();
scanf("%d%d",&n,&m);
for(int i = , u, v, dis;i <= m; i ++)
{
scanf("%d%d%d",&u,&v,&dis);
if(u != v)
add1(u,v,dis);
}
scanf("%d%d",&s,&t);
dfs_s();
dfs_t(); for(int u = ;u <= n ;u ++)
{
for(int i =head1[u]; i != -; i =edge1[i].next)
{
int v = edge1[i].to;
int flow = edge1[i].flow;
if(dis_s[u] + dis_t[v] + flow == dis_s[t]) //这条边为最短路上的边
{
add2(u,v,);add2(v,u,);
}
}
}
printf("%d\n",Dinic());
}
return ;
}

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

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

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

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

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

  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. hdu 3416 Marriage Match IV 【 最短路 最大流 】

    求边不可重复的最短路条数 先从起点到终点用一次dijkstra,再从终点到起点用一次dijkstra,来判断一条边是否在最短路上 如果在,就将这条边的两个端点连起来,容量为1 再跑一下dinic(), ...

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

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

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

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

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

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

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

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

随机推荐

  1. jsPDF – 基于 HTML5 的强大 PDF 生成工具

    jsPDF 是一个基于 HTML5 的客户端解决方案,用于生成各种用途的 PDF 文档. 使用方法很简单,只要引入 jsPDF 库,然后调用内置的方法就可以了. 米扑科技项目用到了HHTML5生成PD ...

  2. Java集合框架之简述

    Java集合框架简述 Java中的集合类是一种工具类,就像是容器,存储任意数量的具有共同属性的对象,集合框架是一个用来代表和操纵集合的统一架构,包含如下部分: 1.接口: 接口是代表集合的抽象数据类型 ...

  3. Centos安装JIRA 7.13版本(自己在官方下载最新版)以及破解

    后半部分流程来自:https://www.cnblogs.com/kaola8023/p/6950481.html 安装准备(切记将许可证号备份) 1.准备mysql需要5.6以及以上的版本(注意:建 ...

  4. 初识 Premiere

    本记录基于Premiere Pro CC 2015.3,编号不连贯,以视频编号为准,对应视频没有有用信息的没有记录. 1.3 基本工作界面和预设工作区 将面板独立出来:按住Ctrl拖动窗口 将关闭的面 ...

  5. Visual Studio Code 编辑器使用

      image.png 之前一直都是用 sublime text 作为开发工具,用久了自然而然会觉得生活无趣,而且当时用sublime text 装了很多插件,有些插件不能用,于是决定试试微软的新产品 ...

  6. linux中 ls |wc -l

      linux中 ls |wc -l_百度知道 答 205行,205个字,1920个字节,wc -l只输出文件行数

  7. 梯度下降(Gradient Descent)小结 -2017.7.20

    在求解算法的模型函数时,常用到梯度下降(Gradient Descent)和最小二乘法,下面讨论梯度下降的线性模型(linear model). 1.问题引入 给定一组训练集合(training se ...

  8. Linux版本

    1.内核:Linux内核Kernel目前最新稳定版 3.4  http://www.kernel.org/ 2.发行版本:是一些厂商将Linux系统内核与应用软件和文档包装起来,并提供一些安装界面和系 ...

  9. 电脑上不了网,但是能登录QQ 问题解决方案

    电脑上不了网,但是能登录QQ 问题解决方案 问题现象 个人电脑连上Wifi,打不开百度等网页,但是能登录QQ. 解决方案 1.打开命令提示对话框(Win+R) 2.输入ipconfig/display ...

  10. C# 跨线程更新 UI

    Winforms 跨线程更新 UI 在 Winforms 中, 所有的控件都包含 InvokeRequired 属性, 如果我们要更新UI,通过它我们可以判断是否需要调用 [Begin]Invoke. ...