hdu 6852Path6(最短路+最小割)
•题意
有n个城市,标号1-n
现花费最小的代价堵路
使得从1号城市到n号城市的路径边长
(注意只是变长不是最长)
堵一条路的代价是这条路的权值
•思路
在堵路以前,从1到n的最小路径当然是最短路
想要路径边长就要在最短路上动手脚
把从1到n的最短路找出来形成一个最短路图,
然后用最小的代价使得最短路图不连通
也就是求这个最短路图的最小割
那怎么建这个最短路图呢?
分别以1和n为源点跑一遍dijkstra,找出每个点到1和n的最短路
设$dis[1][i]$为1到i的最短路,$dis[n][i]$为i到n的最短路
$1->u->v->n$是$1->n$的一条最短路即$dis[1][u]+w[u->v]+dis[n][v]=dis[1][n]$
那么,u->v是1->n最短路上的一条边,加入最短路图中
(由于代码被某人嫌弃太乱,所以对dijkstra和dinic封装了一下...)
•代码
(未封装版)
#include<bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define INF 0x3f3f3f3f3f3f3f3f
#define P pair<long long,int>
const int maxn=1e5+;
int n,m;
struct Edge
{
int v;
ll w;
int next;
}de[maxn],fe[maxn],e[maxn]; int head1[maxn],head2[maxn];
int cnt1,cnt2;
void add(int u,int v,ll w)
{
de[++cnt1]={v,w,head1[u]};
head1[u]=cnt1; fe[++cnt2]={u,w,head2[v]};
head2[v]=cnt2;
} ll dis1[maxn],disn[maxn];
bool vis1[maxn],visn[maxn];
priority_queue<P,vector<P>,greater<P> >pq; void dijkstra()
{
while(!pq.empty())
pq.pop();
for(int i=;i<=n;i++)
dis1[i]=INF,vis1[i]=;
dis1[]=;
pq.push(make_pair(,));
while(!pq.empty())
{
int u=pq.top().second;
pq.pop();
if(!vis1[u])
{
vis1[u]=;
for(int i=head1[u];~i;i=de[i].next)
{
int v=de[i].v;
dis1[v]=min(dis1[v],dis1[u]+de[i].w);
pq.push(make_pair(dis1[v],v));
}
}
} while(!pq.empty())
pq.pop();
for(int i=;i<=n;i++)
disn[i]=INF,visn[i]=;
disn[n]=; pq.push(make_pair(,n));
while(!pq.empty())
{
int u=pq.top().second;
pq.pop();
if(!visn[u])
{
visn[u]=;
for(int i=head2[u];~i;i=fe[i].next)
{
int v=fe[i].v;
disn[v]=min(disn[v],disn[u]+fe[i].w);
pq.push(make_pair(disn[v],v));
}
}
}
} int head[maxn],cnt;
int cur[maxn],d[maxn];
void addEdge(int u,int v,ll w)
{
e[++cnt]={v,w,head[u]};
head[u]=cnt; e[++cnt]={u,,head[v]};
head[v]=cnt;
} bool bfs()
{
queue<int> q;
for(int i=;i<=n;i++)
d[i]=-;
d[]=;
q.push();
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u];~i;i=e[i].next)
{
int v=e[i].v;
if(d[v]==-&&e[i].w>)
{
d[v]=d[u]+;
q.push(v);
}
}
}
return d[n]!=-;
} ll dfs(int u,ll flow)
{
ll nowflow=;
if(u==n) return flow;
for(int i=cur[u];~i;i=e[i].next)
{
cur[u]=i;
int v=e[i].v;
if(d[v]==d[u]+&&e[i].w>)
{
ll k=dfs(v,min(flow-nowflow,e[i].w));
if(k)
{
nowflow+=k;
e[i].w-=k;
e[i^].w+=k;
if(nowflow==flow)
break;
}
}
}
if(!nowflow) d[u]=-;
return nowflow;
} ll Dinic()
{
ll ans=;
while(bfs())
{
for(int i=;i<=n;i++)
cur[i]=head[i]; ans+=dfs(,INF);
}
return ans;
} void Init()
{
mem(head1,-);
mem(head2,-);
mem(head,-);
cnt1=cnt2=cnt=-;
} int main()
{
// freopen("C:\\Users\\14685\\Desktop\\C++workspace\\in&out\\contest","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
Init();
for(int i=;i<=m;i++)
{
int u,v;
ll w;
scanf("%d%d%lld",&u,&v,&w);
add(u,v,w);
} dijkstra(); for(int u=;u<=n;u++)
{
for(int i=head1[u];~i;i=de[i].next)
{
int v=de[i].v;
if(dis1[u]+disn[v]+de[i].w==dis1[n])
{
// printf("***%d %d %d\n",u,v,de[i].w);
addEdge(u,v,de[i].w);
}
}
} printf("%lld\n",Dinic());
}
}(封装版)
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pli pair<ll,int>
#define INF 0x3f3f3f3f3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
const int maxn=1e5+;
int n,m;
struct Edge
{
int v;
ll w;
int next;
}G[maxn<<],e[maxn<<];
int dhead[maxn],dcnt;
void addEdge(int u,int v,ll w)
{
G[++dcnt]={v,w,dhead[u]};
dhead[u]=dcnt;
} struct Dij
{
ll dis[][maxn];
bool vis[maxn];
priority_queue<pli,vector<pli>,greater<pli> > q;
void dij(int s,int n,bool ok)
{
for(int i=;i<=n;i++)
dis[ok][i]=INF,vis[i]=;
dis[ok][s]=;
q.push({,s});
while(!q.empty())
{
int u=q.top().second;
q.pop();
if(vis[u])
continue;
vis[u]=;
for(int i=dhead[u];~i;i=G[i].next)
{
///偶数是正向边,ok=true是正向边
if(ok && i&)
continue;
///奇数是反向边,ok=false是反向边
if(!ok && !(i&))
continue; int v=G[i].v;
ll w=G[i].w;
if(dis[ok][v]>dis[ok][u]+w)
{
dis[ok][v]=dis[ok][u]+w;
if(!vis[v])
q.push({dis[ok][v],v});
}
}
}
}
}dij; int head[maxn],cnt;
void add(int u,int v,ll w)
{
e[++cnt]={v,w,head[u]};
head[u]=cnt;
}
struct Dinic
{
int cur[maxn],d[maxn];
int s=,t=n;
bool bfs()
{
queue<int> q;
for(int i=;i<=n;i++)
d[i]=-;
d[]=;
q.push();
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u];~i;i=e[i].next)
{
int v=e[i].v;
if(d[v]==-&&e[i].w>)
{
d[v]=d[u]+;
q.push(v);
}
}
}
return d[n]!=-;
} ll dfs(int u,ll flow)
{
ll nowflow=;
if(u==n) return flow;
for(int i=cur[u];~i;i=e[i].next)
{
cur[u]=i;
int v=e[i].v;
if(d[v]==d[u]+&&e[i].w>)
{
ll k=dfs(v,min(flow-nowflow,e[i].w));
if(k)
{
nowflow+=k;
e[i].w-=k;
e[i^].w+=k;
if(nowflow==flow)
break;
}
}
}
if(!nowflow) d[u]=-;
return nowflow;
} ll din()
{
ll ans=;
while(bfs())
{
for(int i=;i<=n;i++)
cur[i]=head[i]; ans+=dfs(,INF);
}
return ans;
}
}_din; void Init()
{
mem(dhead,-);
dcnt=-;
mem(head,-);
cnt=-;
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
Init();
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
int u,v;
ll w;
scanf("%d%d%lld",&u,&v,&w);
///跑1到其他点的最短路 加正向边
addEdge(u,v,w);
///跑n到其他点的最短路 加反向边
addEdge(v,u,w);
} dij.dij(,n,true);
dij.dij(n,n,false); for(int u=;u<=n;u++)
{
for(int i=dhead[u];~i;i=G[i].next)
{
int v=G[i].v;
ll w=G[i].w;
if(dij.dis[][u]+dij.dis[][v]+w==dij.dis[][n])
{
add(u,v,w);
add(v,u,);
}
}
}
printf("%lld\n",_din.din());
}
}
hdu 6852Path6(最短路+最小割)的更多相关文章
- 【bzoj1266】[AHOI2006]上学路线route 最短路+最小割
题目描述 可可和卡卡家住合肥市的东郊,每天上学他们都要转车多次才能到达市区西端的学校.直到有一天他们两人参加了学校的信息学奥林匹克竞赛小组才发现每天上学的乘车路线不一定是最优的. 可可:“很可能我们在 ...
- HDU 5889 Barricade(最短路+最小割)
http://acm.hdu.edu.cn/showproblem.php?pid=5889 题意: 给出一个图,帝国将军位于1处,敌军位于n处,敌军会选择最短路到达1点.现在帝国将军要在路径上放置障 ...
- HDU 5889 Barricade(最短路+最小割水题)
Barricade Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total ...
- hdu 3870(平面图最小割转最短路)
Catch the Theves Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 65768/32768 K (Java/Others) ...
- [2019杭电多校第一场][hdu6582]Path(最短路&&最小割)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6582 题意:删掉边使得1到n的最短路改变,删掉边的代价为该边的边权.求最小代价. 比赛时一片浆糊,赛后 ...
- hdu 4289 Control(最小割 + 拆点)
http://acm.hdu.edu.cn/showproblem.php?pid=4289 Control Time Limit: 2000/1000 MS (Java/Others) Mem ...
- 【求出所有最短路+最小割】【多校第一场】【G题】
题意 A从1要追在N的 B 只能走最短的路 问B最少切断多少条路可以让A不能过来 问B最多切断多少条路A还是能过来 对于1 求出1到N的所有最短路的路径,对其求最小割 对于2 求出长度最小的最短路即可 ...
- BZOJ1266 AHOI2006上学路线(最短路+最小割)
求出最短路后找出可能在最短路上的边,显然割完边后我们需要让图中这样的边无法构成1到n的路径,最小割即可,非常板子. #include<iostream> #include<cstdi ...
- HDU 4859 海岸线(最小割+最大独立点权变形)
http://acm.hdu.edu.cn/showproblem.php?pid=4859 题意: 欢迎来到珠海!由于土地资源越来越紧张,使得许多海滨城市都只能依靠填海来扩展市区以求发展.作为Z市的 ...
随机推荐
- 日志 5.27 关于AssetBundle
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/zxsean/article/details/27228783 大概日志就这么写的吧.没什么太专业的东 ...
- JPA使用nativequery多表关联查询返回自定义实体类
本文为JPA的学习采坑,如有问题欢迎指正. JPA官方推荐的多表关联查询使用不便,接触的有些项目可能会使用JPA 做简单查询,Mybaits做复杂查询.所以想要寻找一种好用的解决方案. JPA多表关联 ...
- C# 从零开始写 SharpDx 应用 画三角
原文:C# 从零开始写 SharpDx 应用 画三角 版权声明:博客已迁移到 https://blog.lindexi.com 欢迎访问.如果当前博客图片看不到,请到 https://blog.lin ...
- uda 1.C++ 函数
函数:Python vs C++ 在 Python 和 C++ 中,函数的作用相同:函数把语句组合在一起,执行某种任务.函数可以帮助你避免重复地复制和粘贴相同的代码. 函数编写的语法有些不同,主要有三 ...
- python中'0b111'中的b 是什么意思
https://zhidao.baidu.com/question/987330764742072579.html binary,二进制的意思
- 【Vue】基于nodejs的vue项目打包编译部署
一·项目编译 1·进入项目目录下的终端执行命令 npm run build 正常情况如下图,如遇到错误不会编译成功,且编译后的html文件不能正常渲染. 2·编译完成后进入项目下的dist目录运行生成 ...
- js如何获取地址栏上的参数id
直接上js代码 方法1: 父页面跳转地址栏带id>>>>window.location.href='${ctxAdmin}/study/checkForm?id='+id+ ...
- ifram子页面与父页面的方法相互调用
parent.html <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:/ ...
- CODE FESTIVAL 2017 qual A C Palindromic Matrix(补题)
彩笔看到题目后,除了懵逼,没有啥反应了,唯一想的就是 这是不是dp啊?看了题解才发现,原来是这样啊. 画几个矩阵看看就能看出来规律. 思路:先假设这是个M * N的矩阵 如果M和N都是偶数,则每个出现 ...
- Jieba分词原理与解析
https://www.jianshu.com/p/dfdfeaa7d01f 1 HMM模型 image.png 马尔科夫过程: image.png image.png 以天气判断为例:引 ...