(最小割)Path
http://acm.hdu.edu.cn/showproblem.php?pid=6582
思路:找到最短路核心边建图,跑一遍最小割,最短路核心边的定义为设起点到每个点的最短距离为d[i],每个点到终点的最短路为d2[i],如果一条边起点为u,终点为v,边权为w,若d[u]+d2[v]+w==d[n]则这是一条最短路核心边。所以先用spfa求d[i],然后反向spfa求d2[i],最后建图dinic求出答案。
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<cstdio>
#include<stack>
#include<cmath>
#include<iostream>
#define ll long long
#define lowbit(x) x&(-x)
using namespace std;
const int maxn=;
const int maxm=;
const ll inf=1e18;
struct node{
int u,v,nxt;
ll w;
}e[*maxm],e2[*maxm],e3[*maxm];
int h[maxn],h2[maxn],h3[maxn],depth[maxn];
ll d[maxn],d2[maxn];
bool vis[maxn];
int n,m,st,ed,cnt,cnt2,cnt3;
void init()
{
memset(h,-,sizeof(h));
memset(h2,-,sizeof(h2));
memset(h3,-,sizeof(h3));
for(int i=;i<=n;i++)
d[i]=d2[i]=inf;
cnt=cnt2=cnt3=;
} void add(int u,int v,ll w)//正向建边
{
e[cnt].u=u,e[cnt].v=v,e[cnt].w=w;
e[cnt].nxt=h[u];h[u]=cnt++;
} void add2(int u,int v,ll w)//反向建边
{
e2[cnt2].u=u,e2[cnt2].v=v,e2[cnt2].w=w;
e2[cnt2].nxt=h2[u],h2[u]=cnt2++;
}
void add3(int u,int v,ll w)//重新建边
{
e3[cnt3].u=u,e3[cnt3].v=v,e3[cnt3].w=w;
e3[cnt3].nxt=h3[u],h3[u]=cnt3++;
} bool spfa()//求每点到1的最短距离
{
queue<int> q;
memset(vis,,sizeof(vis));
d[st]=;
vis[st]=;
q.push(st);
while(!q.empty())
{
int u=q.front();q.pop();
vis[u]=;
for(int i=h[u];i!=-;i=e[i].nxt)
{
int v=e[i].v;
ll w=e[i].w;
if(d[v]>d[u]+w)
{
d[v]=d[u]+w;
if(!vis[v])
{
vis[v]=;
q.push(v);
}
}
}
}
return d[n]==inf;
} void re_spfa()//求每点到n的最短距离
{
queue<int> q;
memset(vis,,sizeof(vis));
d2[ed]=;
vis[ed]=;
q.push(ed);
while(!q.empty())
{
int u=q.front();q.pop();
vis[u]=;
for(int i=h2[u];i!=-;i=e2[i].nxt)
{
int v=e2[i].v;
ll w=e2[i].w;
if(d2[v]>d2[u]+w)
{
d2[v]=d2[u]+w;
if(!vis[v])
{
vis[v]=;
q.push(v);
}
}
}
}
} void create_map()//重新建边
{
for(int i=;i<cnt;i++)
{
int u=e[i].u;
int v=e[i].v;
ll w=e[i].w;
if((d[u]+d2[v]+w==d[ed])&&(d[u]<inf&&d2[v]<inf))
{//最短路核心边
add3(u,v,w);
add3(v,u,);
}
}
} bool bfs(){//dinic分层
queue<int> que;
memset(depth,,sizeof(depth));
que.push(st);
depth[st]=;
while(!que.empty()){
int u=que.front();
que.pop();
if(u==ed)
return true;
for(int i=h3[u];i!=-;i=e3[i].nxt){
int v=e3[i].v;
ll w=e3[i].w;
if(!depth[v]&&w){
depth[v]=depth[u]+;
que.push(v);
}
}
}
return false;
} ll dfs(int u,ll dis)
{
if(u==ed)
return dis;
ll res=;
for(int i=h3[u];i!=-;i=e3[i].nxt)
{
int v=e3[i].v;
ll w=e3[i].w;
if((depth[v]==depth[u]+)&&w)
{
ll di=dfs(v,min(w,dis-res));
e3[i].w-=di;
e3[i^].w+=di;
res+=di;
if(res==dis)
return dis;
}
}
return res;
} void dinic()//dinic求最小割
{
ll ans=;
while(bfs())
{
ans+=dfs(st,inf);
}
printf("%lld\n",ans);
} int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
st=,ed=n;
init();
for(int i=;i<m;i++)
{
int u,v;ll w;
scanf("%d%d%lld",&u,&v,&w);
add(u,v,w);
add2(v,u,w);
}
if(spfa())//特判,没有最短路
printf("0\n");
else
{
re_spfa();
create_map();
dinic();
}
}
return ;
}
(最小割)Path的更多相关文章
- 2019 Multi-University Training Contest 1 E Path(最短路+最小割)
题意 链接:https://vjudge.net/problem/HDU-6582 给定一个有向图,可以有重边,每条边上有一个权值表示删掉这条边的代价,问最少花费多少代价能使从s到t节点的最短路径增大 ...
- 2019HDU多校Path——最短路最小割
题目 给出一个 $n$ 个顶点 $m$ 条边的图,要求阻塞一些边,使得从 $1$ 到 $n$ 的最短路变长,求阻塞的边长度和的最小值,不必保证阻塞后可达. 分析 很显然,要阻塞的边肯定在最短路图上,先 ...
- HDU6582 Path【优先队列优化最短路 + dinic最大流 == 最小割】
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6582 来源:2019 Multi-University Training Contest 1 题目大意 ...
- [2019杭电多校第一场][hdu6582]Path(最短路&&最小割)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6582 题意:删掉边使得1到n的最短路改变,删掉边的代价为该边的边权.求最小代价. 比赛时一片浆糊,赛后 ...
- 2019 Multi-University Training Contest 1 Path(最短路+最小割)
题意:给你n个点 m条边 现在你能够堵住一些路 问怎样能让花费最少且让1~n走的路比最短路的长度要长 思路:先跑一边最短路 建一个最短路图 然后我们跑一边最大流求一下最小割即可 #include &l ...
- 最大流-最小割 MAXFLOW-MINCUT ISAP
简单的叙述就不必了. 对于一个图,我们要找最大流,对于基于增广路径的算法,首先必须要建立反向边. 反向边的正确性: 我努力查找了许多资料,都没有找到理论上关于反向边正确性的证明. 但事实上,我们不难理 ...
- POJ 2125 Destroying The Graph (二分图最小点权覆盖集+输出最小割方案)
题意 有一个图, 两种操作,一种是删除某点的所有出边,一种是删除某点的所有入边,各个点的不同操作分别有一个花费,现在我们想把这个图的边都删除掉,需要的最小花费是多少. 思路 很明显的二分图最小点权覆盖 ...
- ZOJ 2587 Unique Attack (最小割唯一性)
题意 判断一个无向图的割是否唯一 思路 错误思路:一开始想的是判断割边是否都是关键割边,那既然割边两端点能连通S.T点的边是关键边,那么只要遇到有某个边两端点不连通S or T则这条边就不是关键割边( ...
- POJ 3469 Dual Core CPU (最小割建模)
题意 现在有n个任务,两个机器A和B,每个任务要么在A上完成,要么在B上完成,而且知道每个任务在A和B机器上完成所需要的费用.然后再给m行,每行 a,b,w三个数字.表示如果a任务和b任务不在同一个机 ...
随机推荐
- python 设置开机启动脚本
1.创建python_auto.bat的快捷方式,放入启动项: C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\ ...
- Java JDK安装教程以及JDK多版本间快速切换配置
原本想自己写一篇,结果在网上发现一篇写的特别好的博文,大家可以去原网址围观浏览加点赞, 只是搬运工+迷弟. 原文地址:https://blog.csdn.net/qq_38916130/article ...
- 003/kubernetes基础:开启云原生之门(Mooc)
一.简介:(https://www.imooc.com/learn/978) 在2017年Kubernetes战胜了两个强大的竞争对手Swarm和Mesos,成为容器管理与调度编排领域的首选平台和事实 ...
- OuterXml和InnerXml(2)
官方例子:https://msdn.microsoft.com/en-us/library/system.xml.xmlnode.outerxml.aspx using System; using S ...
- python函数-基础知识
一.含义函数是程序内的“小程序” 二.示例 #!/usr/bin/env python #coding:utf-8 def hello(): print('Hello world!') print(' ...
- mysql 主从 设置
总结:1.如果是虚拟克隆mysql 请注意auto.cnf的uuid保证不一样,即删除auto.cnf 重新启动即可2.默认安装的mysql配置文件mysqld.cnf可能绑定了127.0.0.1 只 ...
- [19/05/17-星期五] HTML_body标签(内嵌标签)和框架标签
一.内嵌标签 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <!- ...
- [2019杭电多校第五场][hdu6629]string matching(扩展kmp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6629 题意求字符串的每个后缀与原串的最长公共前缀之和. 比赛时搞东搞西的,还搞了个后缀数组...队友一 ...
- 6、 逻辑回归(Logistic Regression)
6.1 分类问题 在分类问题中,你要预测的变量
- ssh1
#coding=utf-8 import paramiko ssh = paramiko.SSHClient() #允许链接不在linux上.ssh文件中不在known_hosts文件中的主机 ssh ...