HDU6582 Path【优先队列优化最短路 + dinic最大流 == 最小割】
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6582
来源:2019 Multi-University Training Contest 1
题目大意:
给定一张有向图,可以阻碍若干条有向边,花费为边的权值,求使其最短路变得更长所需的最小花费。
解题思路:
1.因为最短路可能是多条,所以找出最短路网络,然后在最短路网络中跑最小割,即最大流。就切断了原先的最短路且保证了是最小花费(最小割)。
2.值得注意的地方:边的长度限制为1e9,所以最短路数组以及一些其他的求和的值要开long long型,防止爆。
3.求最短路核心边需满足 dis[u] + edge[i].w == dis[v]。那么edge[i].w就是一条最短路的核心边。同时要确保合法性,满足dis[u] != inf && dis[v] != inf
代码如下:
#include<stdio.h>
#include<string.h>
#include<queue>
#define LL long long
#define mem(a, b) memset(a, b, sizeof(a))
const int MAXN = 1e4 + ;
const LL inf = 0x3f3f3f3f;
using namespace std; int n, m;//n个点 m条有向边
int vis[MAXN];//源点到该点的最短距离是否被确定
LL dis[MAXN]; struct Edge
{
int to, next;
LL w;
}e[MAXN];
int head[MAXN], cnt; void add(int a, int b, int c)
{
e[++ cnt].to = b;
e[cnt].w = c;
e[cnt].next = head[a];
head[a] = cnt;
} struct Node
{
int pot;
LL dis; //点 以及 源点到该点的最短距离
bool operator < (const Node &a)const//重载 按照dis从小到大排序
{
return dis > a.dis;
}
}no; priority_queue<Node> Q;
void dij() //优先队列优化的最短路
{
mem(vis, ), mem(dis, inf);
no.dis = , no.pot = ;
dis[] = ;
Q.push(no);
while(!Q.empty())
{
Node a = Q.top();//优先队列无front操作
Q.pop();
if(vis[a.pot])
continue;
vis[a.pot] = ;
for(int i = head[a.pot]; i != -; i = e[i].next)//松弛操作
{
int to = e[i].to;
if(!vis[to] && dis[a.pot] + e[i].w < dis[to])
{
dis[to] = dis[a.pot] + e[i].w;
no.pot = to, no.dis = dis[to];
Q.push(no);
}
}
}
// printf("%d\n", dis[n]);
} struct edge_
{
int to, next, flow;
}e_[ * MAXN];//要加反向边 开2倍
int head_[MAXN]; void add_(int a, int b, int c)
{
e_[++ cnt].to = b;
e_[cnt].flow = c;
e_[cnt].next = head_[a];
head_[a] = cnt;
} int dep[MAXN];
int bfs(int st, int ed)
{
if(st == ed)
return ;
mem(dep, -);
queue<int >Q_;
dep[st] = ;
Q_.push(st);
while(!Q_.empty())
{
int now = Q_.front();
Q_.pop();
for(int i = head_[now]; i != -; i = e_[i].next)
{
int to = e_[i].to;
if(e_[i].flow > && dep[to] == -)
{
dep[to] = dep[now] + ;
Q_.push(to);
}
}
}
return dep[ed] != -;
} int dfs(int now, int ed, int inc)
{
if(now == ed)
return inc;
for(int i = head_[now]; i != -; i = e_[i].next)
{
int to = e_[i].to;
if(e_[i].flow > && dep[to] == dep[now] + )
{
int min_flow = dfs(to, ed, min(inc, e_[i].flow));
if(min_flow > )
{
e_[i].flow -= min_flow;
e_[i ^ ].flow += min_flow;
return min_flow;
}
}
}
return -;
} LL dinic(int st, int ed)
{
LL ans = ;
while(bfs(st, ed))
{
while()
{
int inc = dfs(st, ed, inf);
if(inc == -)
break;
ans += inc;
}
}
return ans;
} int main()
{
int T;
scanf("%d", &T);
while(T --)
{
scanf("%d%d", &n, &m);
cnt = , mem(head, -); //最短路的边从1开始存 head初始化为-1
for(int i = ; i <= m; i ++)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
add(a, b, c); //有向边 加一条即可
}
dij(); //跑最短路
if(dis[n] == inf) //特判
{
printf("0\n");
continue;
}
cnt = -, mem(head_, -);//从0开始存 才能进行 ^ 运算
for(int i = ; i <= n; i ++)
{
for(int j = head[i]; j != -; j = e[j].next)
{
int to = e[j].to;
if(dis[i] + e[j].w == dis[to] && dis[to] != inf && dis[i] != inf) //得到最短路核心边(因为可能是多条)
{
add_(i, to, e[j].w);
add_(to, i, ); //反向边容量为 0
}
}
}
printf("%lld\n", dinic(, n));
}
return ;
}
优先队列优化dij+最大流dinic
HDU6582 Path【优先队列优化最短路 + dinic最大流 == 最小割】的更多相关文章
- 2020牛客暑期多校训练营 第二场 I Interval 最大流 最小割 平面图对偶图转最短路
		LINK:Interval 赛时连题目都没看. 观察n的范围不大不小 而且建图明显 考虑跑最大流最小割. 图有点稠密dinic不太行. 一个常见的trick就是对偶图转最短路. 建图有点复杂 不过建完 ... 
- hdu  2435 dinic算法模板+最小割性质
		#include<stdio.h> #include<queue> #include<string.h> using namespace std; #define ... 
- 晴天小猪历险记之Hill(Dijkstra优先队列优化)
		描述 这一天,他来到了一座深山的山脚下,因为只有这座深山中的一位隐者才知道这种药草的所在.但是上山的路错综复杂,由于小小猪的病情,晴天小猪想找一条需时最少的路到达山顶,但现在它一头雾水,所以向你求助. ... 
- 2019HDU多校Path——最短路最小割
		题目 给出一个 $n$ 个顶点 $m$ 条边的图,要求阻塞一些边,使得从 $1$ 到 $n$ 的最短路变长,求阻塞的边长度和的最小值,不必保证阻塞后可达. 分析 很显然,要阻塞的边肯定在最短路图上,先 ... 
- Luogu2046 NOI2010 海拔 平面图、最小割、最短路
		传送门 首先一个不知道怎么证的结论:任意点的\(H\)只会是\(0\)或\(1\) 那么可以发现原题的本质就是一个最小割,左上角为\(S\),右下角为\(T\),被割开的两个部分就是\(H=0\)与\ ... 
- cf786E ALT (最小割+倍增优化建图)
		如果把“我全都要”看作是我全不要的话,就可以用最小割解决啦 源点S,汇点T 我们试图让每个市民作为一个等待被割断的路径 把狗狗给市民:建边(S,i,1),其中i是市民 把狗狗给守卫:建边(j,T,1) ... 
- 最短路算法模板合集(Dijkstar,Dijkstar(优先队列优化), 多源最短路Floyd)
		再开始前我们先普及一下简单的图论知识 图的保存: 1.邻接矩阵. G[maxn][maxn]; 2.邻接表 邻接表我们有两种方式 (1)vector< Node > G[maxn]; 这个 ... 
- POJ 1511 Invitation Cards(单源最短路,优先队列优化的Dijkstra)
		Invitation Cards Time Limit: 8000MS Memory Limit: 262144K Total Submissions: 16178 Accepted: 526 ... 
- hdu 1874(最短路 Dilkstra +优先队列优化+spfa)
		畅通工程续 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ... 
随机推荐
- [secureCRT] 关闭secureCRT的auto print功能
			说明:每次不小心按到secureCRT的auto print时,secure总是会自动打印,结果打印出一堆没用的日志.....切换选项页时不小心按到的,还是挺浪费纸的.怎样才能关闭这个功能呢 实现:想 ... 
- 第三章、HTTP报文
			1 报文流 HTTP 报文是在 HTTP 应用程序之间发送的数据块.这些数据块以一些文本形式的元信息(meta-information)开头.这些报文在客户端.服务器和代理之间流动.术语“流入”.“流 ... 
- ROS机器人开发实践学习笔记1
			刚刚开始学习ROS,打算入机器人的坑了,参考教材是<ROS及其人开发实践>胡春旭编著 机械工业出版社 华章科技出品.本来以为可以按照书上的步骤一步步来,但是,too young to si ... 
- php-fpm脚本
			#! /bin/sh ### BEGIN INIT INFO # Provides: php-fpm # Required-Start: $remote_fs $network # Required- ... 
- 第11组 Beta冲刺(1/5)
			第11组 Beta冲刺(1/5) 队名 不知道叫什么团队 组长博客 https://www.cnblogs.com/xxylac/p/11913626.html 作业博客 https://www. ... 
- 牛顿法与拟牛顿法(四) BFGS 算法
			转自 https://blog.csdn.net/itplus/article/details/21897443 
- idea 使用maven 下载源码包
			方式1:全量下载源码包 方式二:下载单个源码包 随便找个源码可以看到文件上有download (标识下载源码包) choose sources表示选择那个版本的源码包 
- 使用Vagrant配置本地开发环境
			从二零一四年开始使用vagrant+VirtualBox搭建linux开发环境,配置简单灵活,后台运行占用内存少,比vmware好用很多,果断弃用vmware转投vagrant的怀抱:无论是个人搭建开 ... 
- java中 label 配合 break continue 使用方法
			转 https://www.jianshu.com/p/7954b61bc6ee java中 label 配合 break continue 使用的其实是比较少的. 这种做法在业务代码中比较少见. 在 ... 
- Class.ForName()读取配置文件
			榨汁机(Juicer)榨汁的案例 分别有水果(Fruit)苹果(Apple)香蕉(Banana)桔子(Orange)榨汁(squeeze) public class Demo_Reflect { /* ... 
