题目:http://acm.hdu.edu.cn/showproblem.php?pid=6582

Path

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 3747    Accepted Submission(s): 1075

Problem Description
Years later, Jerry fell in love with a girl, and he often walks for a long time to pay visits to her. But, because he spends too much time with his girlfriend, Tom feels neglected and wants to prevent him from visiting her.
After doing some research on the neighbourhood, Tom found that the neighbourhood consists of exactly n houses, and some of them are connected with directed road. To visit his girlfriend, Jerry needs to start from his house indexed 1 and go along the shortest path to hers, indexed n. 
Now Tom wants to block some of the roads so that Jerry has to walk longer to reach his girl's home, and he found that the cost of blocking a road equals to its length. Now he wants to know the minimum total cost to make Jerry walk longer.
Note, if Jerry can't reach his girl's house in the very beginning, the answer is obviously zero. And you don't need to guarantee that there still exists a way from Jerry's house to his girl's after blocking some edges.
 
Input
The input begins with a line containing one integer T(1≤T≤10), the number of test cases.
Each test case starts with a line containing two numbers n,m(1≤n,m≤10000), the number of houses and the number of one-way roads in the neighbourhood.
m lines follow, each of which consists of three integers x,y,c(1≤x,y≤n,1≤c≤109), denoting that there exists a one-way road from the house indexed x to y of length c.
 
Output
Print T lines, each line containing a integer, the answer.
 
Sample Input
1
3 4
1 2 1
2 3 1
1 3 2
1 3 3
 
Sample Output
3
 
Source
 
Recommend
We have carefully selected several similar problems for you:  6718 6717 6716 6715 6714 

题意:

给n个节点m条有向边,现在可以删去一些边,代价为边权,问最小代价删去一些边使得现在节点1到节点n的最短路不成立(如果1不可达n则答案为0)

思路:

可能有多条1到n的最短路,这些最短路组成图,以最小代价使图不连通就是求最小割,由最大流最小割定理可知,最小割等于最大流,所以我们先找出图中1到n的最短路新建一个图,在这个图上从1到n跑一边最大流就可求出答案
现在就是建图的问题,我们先得到1到n的最短路径dis[i],再得到n到1的最短路径dis1[i],再把原图中符合dis[u]+e[i].w+dis1[v]==dis[n](令e[i].w为节点u到v的边权)的边建一个新图,
在这个新图上从1到n跑一边dinic就可得到答案

注意:

调了一个下午,在bool operator(const node &a)const{return a.w<w;}中原来是要a.w<w才能让优先队列中w小的优先,如果是a.w>w则是w大的优先

 #include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int amn=1e4+;
const ll inf=1e18;
struct edge{
int from,to,nex;ll w;
}eg[amn],eg1[amn],e[amn<<|];
struct node{
int p;
ll w;
node(int pp,ll ww){p=pp;w=ww;}
bool operator<(const node &a)const{return a.w<w;} ///调了一个下午,原来是要a.w<w才行,这样优先队列中才会w小的优先,如果是a.w>w则是w大的优先
};
ll head[amn],egn,head1[amn],egn1,n,m,dis[amn],dis1[amn],vis[amn],head2[amn],egn2;
void init(int n){
egn=,egn1=,egn2=; ///egn2是跑最大流的,初始为1,这样就可以从2开始加边,这样正向边和反向边相邻储存,因为2^1=3,3^1=2...所以可以异或得到正向边反向边
for(int i=;i<=n;i++)head2[i]=head1[i]=head[i]=;
}
void add(int u,int v,ll w){ ///正向图加边
eg[++egn].nex=head[u];
head[u]=egn;
eg[egn].from=u;
eg[egn].to=v;
eg[egn].w=w;
}
void add1(int u,int v,ll w){ ///反向图加边
eg1[++egn1].nex=head1[u];
head1[u]=egn1;
eg1[egn1].from=u;
eg1[egn1].to=v;
eg1[egn1].w=w;
}
void add2(int u,int v,ll w){ ///跑最大流的新图加边
e[++egn2].nex=head2[u];
head2[u]=egn2;
e[egn2].from=u;
e[egn2].to=v;
e[egn2].w=w;
} ///以1为起点跑最短路
void dijkstra(int s){
memset(vis,,sizeof vis);
for(int i=;i<=n;i++)dis[i]=inf;
dis[s]=;
priority_queue<node> q;
q.push(node(s,dis[s]));
while(q.size()){
int u=q.top().p;
ll w=q.top().w;q.pop();
if(w>dis[u])continue;
vis[u]=;
for(int i=head[u];i;i=eg[i].nex){
int v=eg[i].to;
if(!vis[v]&&((dis[v])>(eg[i].w)+(dis[u]))){
dis[v]=(eg[i].w)+dis[u];
q.push(node(v,(dis[v])));
}
}
}
}
///以n为起点跑最短路
void dijkstra1(int s){
memset(vis,,sizeof vis);
for(int i=;i<=n;i++)dis1[i]=inf;
dis1[s]=;
priority_queue<node> q;
q.push(node(s,dis1[s]));
while(q.size()){
int u=q.top().p;
ll w=q.top().w;q.pop();
if(w>dis1[u])continue;
vis[u]=;
for(int i=head1[u];i;i=eg1[i].nex){
int v=eg1[i].to;
if(!vis[v]&&((dis1[v])>(eg1[i].w)+(dis1[u]))){
dis1[v]=(eg1[i].w)+dis1[u];
q.push(node(v,(dis1[v])));
}
}
}
}
///dinic最大流
queue<int> que;
ll dist[amn],src=,sink=n;
void bfs(){
memset(dist,,sizeof dist);
while(que.size())que.pop();
vis[src]=;
que.push(src);
while(que.size()){
int u=que.front();que.pop();
for(int i=head2[u];i;i=e[i].nex){
int v=e[i].to;//cout<<'>'<<e[i].w<<' '<<v<<endl;
if(e[i].w&&!vis[v]){
que.push(v);
dist[v]=dist[u]+;
vis[v]=;
}
}
}
}
int dfs(int u,ll delta){
if(u==sink)return delta;
int ret=;
for(int i=head2[u];delta&&i;i=e[i].nex)
if(e[i].w&&(dist[e[i].to]==dist[u]+)){
ll dd=dfs(e[i].to,min(e[i].w,delta));
e[i].w-=dd;
e[i^].w+=dd;
delta-=dd;
ret+=dd;
}
return ret;
}
ll maxflow(){
ll ret=;
while(){
memset(vis,,sizeof vis);
bfs();
if(!vis[sink])return ret;//cout<<'<'<<ret<<endl;
ret+=dfs(src,inf);
}
}
int main(){
int T,x,y;ll c;
scanf("%d",&T);
while(T--){
scanf("%lld%lld",&n,&m);
init(n); ///初始化
src=,sink=n; ///设置1为源点,n为汇点
for(int i=;i<=m;i++){
scanf("%d%d%lld",&x,&y,&c);
add(x,y,c); ///正向图,为了以1为起点跑最短路
add1(y,x,c); ///反向图,为了以n为起点跑最短路
}
dijkstra(); ///以1为起点的最短路
if(dis[n]==inf){printf("0\n");continue;} ///如果1到n不可达则输出0
dijkstra1(n); ///以n为起点的最短路
for(int i=;i<=egn;i++){
// cout<<eg[i].from<<' '<<eg[i].to<<' '<<eg[i].w<<endl;
// cout<<dis[eg[i].from]<<' '<<eg[i].w<<' '<<dis1[eg[i].to]<<' '<<dis[n]<<endl<<endl;
if(dis[eg[i].from]+eg[i].w+dis1[eg[i].to]==dis[n]){ ///如果1到现在这个点u的最短路径+u到v的边权+v到n的最短路径==1到n的最短路径则u到v这条边是最短路中的一条边
add2(eg[i].from,eg[i].to,eg[i].w); ///建新图,加正向边
add2(eg[i].to,eg[i].from,); ///边权为0的反向边
}
}
printf("%lld\n",maxflow()); ///最大流等于最小割
}
}
/**
给n个节点m条有向边,现在可以删去一些边,代价为边权,问最小代价删去一些边使得现在节点1到节点n的最短路不成立(如果1不可达n则答案为0)
可能有多条1到n的最短路,这些最短路组成图,以最小代价使图不连通就是求最小割,由最大流最小割定理可知,最小割等于最大流,所以我们先找出图中1到n的最短路新建一个图,在这个图上从1到n跑一边最大流就可求出答案
现在就是建图的问题,我们先得到1到n的最短路径dis[i],再得到n到1的最短路径dis1[i],再把原图中符合dis[u]+e[i].w+dis1[v]==dis[n](令e[i].w为节点u到v的边权)的边建一个新图,
在这个新图上从1到n跑一边dinic就可得到答案
调了一个下午,在bool operator(const node &a)const{return a.w<w;}中原来是要a.w<w才能让优先队列中w小的优先,如果是a.w>w则是w大的优先
**/

[最短路,最大流最小割定理] 2019 Multi-University Training Contest 1 Path的更多相关文章

  1. hiho 第116周,最大流最小割定理,求最小割集S,T

    小Hi:在上一周的Hiho一下中我们初步讲解了网络流的概念以及常规解法,小Ho你还记得内容么? 小Ho:我记得!网络流就是给定了一张图G=(V,E),以及源点s和汇点t.每一条边e(u,v)具有容量c ...

  2. hihocoder 网络流二·最大流最小割定理

    网络流二·最大流最小割定理 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi:在上一周的Hiho一下中我们初步讲解了网络流的概念以及常规解法,小Ho你还记得内容么? ...

  3. [HihoCoder1378]网络流二·最大流最小割定理

    思路: 根据最大流最小割定理可得最大流与最小割相等,所以可以先跑一遍EdmondsKarp算法.接下来要求的是经过最小割切割后的图中$S$所属的点集.本来的思路是用并查集处理所有前向边构成的残量网络, ...

  4. 【codevs1907】方格取数3(最大流最小割定理)

    网址:http://codevs.cn/problem/1907/ 题意:在一个矩阵里选不相邻的若干个数,使这些数的和最大. 我们可以把它看成一个最小割,答案就是矩阵中的所有数-最小割.先把矩阵按国际 ...

  5. 牛客暑期第六场G /// 树形DP 最大流最小割定理

    题目大意: 输入t,t个测试用例 每个测试用例输入n 接下来n行 输入u,v,w,树的无向边u点到v点权重为w 求任意两点间的最大流的总和 1.最大流最小割定理 即最大流等于最小割 2.无向树上的任意 ...

  6. 2019 Multi-University Training Contest 1 Path(最短路+最小割)

    题意:给你n个点 m条边 现在你能够堵住一些路 问怎样能让花费最少且让1~n走的路比最短路的长度要长 思路:先跑一边最短路 建一个最短路图 然后我们跑一边最大流求一下最小割即可 #include &l ...

  7. 2019HDU多校第一场 6582 Path 【最短路+最大流最小割】

    一.题目 Path 二.分析 首先肯定要求最短路,然后如何确定所有的最短路其实有多种方法. 1 根据最短路,那么最短路上的边肯定是可以满足$dist[from] + e.cost = dist[to] ...

  8. 【hihocoder 1378】网络流二·最大流最小割定理

    [Link]:http://hihocoder.com/problemset/problem/1378 [Description] [Solution] 在求完最小割(最大流)之后; 可以在剩余网络中 ...

  9. 2019 Nowcoder Multi-University Training Contest 4 E Explorer

    线段树分治. 把size看成时间,相当于时间 $l$ 加入这条边,时间 $r+1$ 删除这条边. 注意把左右端点的关系. #include <bits/stdc++.h> ; int X[ ...

随机推荐

  1. 杂记:VMware中为mac虚拟机扩容

    之前在VMware中安装Mac虚拟机时,硬盘选的是默认的40G,后来用的过程中随着软件的安装,特别是安装完Xcode和QT5.9之后,可用空间只剩不到3G,每次开机之后都会提醒空间不足,需要清理空间, ...

  2. swift中的闭包总结

    闭包是功能性自包含模块,可以在代码中被传递和使用. Swift 中的闭包与 Objective-C中的 blocks 以及其他一些编程语言中的 lambdas 比较相似. 闭包的基本语法 闭包表达式语 ...

  3. 致歉Note7用户后,三星要还给世界下一个机皇

    ​ 1月23日,三星电子在韩国首尔公布了Note7事件原因调查结果.此次认定过程精密而繁琐,最终结果发布距离三星宣布全球召回Note7已经有3个月. 相比事发之初各路信息甚嚣尘上,现在虽然还不能说已经 ...

  4. 【深入理解Java虚拟机】类的初始化过程

    类的初始化过程 类的加载过程.png 加载 将 Class 文件以二进制的形式加载到内存中 验证 校验 Class 文件是否安全,是否被正确的修改等 准备 为类变量申请内存,设置默认值,(初始化变量的 ...

  5. win10 64位 安装JDK1.8

    win10 64位 jdk1.8 配置Java环境,是否安装JRE. 一.安装得有JRE JDK和JRE分别安装再不同的文件夹下 新建:JAVA_HOME 值:JDK的安装路径 新建:CLASSPAT ...

  6. 漫谈国内外Android生态:华为发布的 HMS 服务,对 Mate30 系列无法搭载 Google GMS 的补偿有多大(原创)

    如果既用过iPhone,也用过国际版Android,还用过国内的安卓,(并且这三种都用了半年以上),就能体会到GMS多重要.可以说,iOS的体验大幅度领先于国内的安卓,一多半的原因是国内安卓没有GMS ...

  7. Nginx之反向代理配置(二)

    前文我们聊了Nginx的防盗链.反向代理以及开启nginx代理缓存,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/12417130.html:今天我们继续说ng ...

  8. 微信小程序学习简介

    如何向微信小程序导入DEMO源码: 参考方法 参考学习小程序官方文档 小程序官方文档 小程序目录简介 app.json :设置一些工程全局的量.js : 写一些函数逻辑.wxml: 调用.js中写的函 ...

  9. mongoose .find().limit()返回undefined

    当我们使用mongoose的find方法查询数据库的同时,可以使用limit方法来指定返回数据的条数. limit方法基本语法如下所示: >db.COLLECTION_NAME.find().l ...

  10. 大型Java进阶专题(三) 软件架构设计原则(下)

    前言 ​ 今天开始我们专题的第二课了,本章节继续分享软件架构设计原则的下篇,将介绍:接口隔离原则.迪米特原则.里氏替换原则和合成复用原则.本章节参考资料书籍<Spring 5核心原理>中的 ...