洛谷 P4300 BZOJ 1266 [AHOI2006]上学路线route
题目描述
输入
输出
样例输入
1 2 1 3
2 6 1 5
1 3 1 1
3 4 1 1
4 6 1 1
5 6 1 2
1 5 1 4
样例输出
5
提示
2<=N<=500, 1<=M<=124 750, 1<=ti, ci<=10 000
合肥市的公交网络十分发达,你可以认为任意两个车站间都可以通过直达或转车互相到达,当然如果在你提供的删除方案中,家和学校无法互相到达,那么则认为上学需要的最短为正无穷大:这显然是一个合法的方案。
吐槽
这题各种单向边双向边变来变去,一会单向,一会双向,一会又单向添加两次,各种乱七八糟的,把我自己绕晕了。只是粗浅地搞懂原理,却没真正理解题目意思和解法真的不好啊!
解题思路
第一问单源最短路,才500个点,随便乱搞套各种模板的节奏,这里我选择了代码量极短的Floyd(后面求最小割即最大流时加边比spfa更方便)。
然后第二问,要把所有最短路径都切断,那么我们用Floyd或其他spfa什么的跑出所有最短路构成的图,每条边的切割代价为c,那么求一波这个图的最小割,就是答案了(好像BZOJ 1002 狼抓兔子啊)。由于最小割等于最大流,所以我们在最短路图上跑最大流算法即可,这里我用的Dinic,蒟蒻版几乎无优化。
源代码
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m; struct Edge_road{
int u,v,w,c;
}g[];
int dis[][],num=;
inline void addg(int u,int v,int w,int c)
{
g[num++]={u,v,w,c};//不排序的前向星,只加单向边
dis[u][v]=dis[v][u]=min(dis[u][v],w);//dis数组用来跑floyd,加双向边,有重边则选最小边长的一条边
}
inline void floyd()
{
for(int i=;i<=n;i++) dis[i][i]=;
for(int k=;k<=n;k++)
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
} struct Edge_flow{
int next,to,flow;
}e[];
int cnt=,head[]={};
inline void add(int u,int v,int c)
{
e[cnt]={head[u],v,c};
head[u]=cnt++;
e[cnt]={head[v],u,};
head[v]=cnt++;
} int dep[]={};
bool bfs()
{
memset(dep,,sizeof(dep));
queue<int> q;
dep[]=;
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].to;
if(!dep[v]&&e[i].flow)
{
dep[v]=dep[u]+;
q.push(v);
}
}
}
return dep[n]!=;
} int dfs(int u,int f)
{
if(u==n||f==) return f;
int sum=;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
if(dep[v]==dep[u]+&&e[i].flow)
{
int delta=dfs(v,min(f-sum,e[i].flow));
sum+=delta;
e[i].flow-=delta;
e[i^].flow+=delta;
if(f-sum<=) break;
}
}
if(!sum) dep[u]=-;
return sum;
}
int main()
{
scanf("%d%d",&n,&m);
memset(dis,0x3f,sizeof(dis));
memset(g,-,sizeof(-));
for(int i=,u,v,w,c;i<=m;i++)
{
scanf("%d%d%d%d",&u,&v,&w,&c);
addg(u,v,w,c);
}
floyd();
printf("%d\n",dis[][n]);
for(int i=;i<=m;i++)
{
int u=g[i].u,v=g[i].v,w=g[i].w,c=g[i].c;
if(dis[][u]+w+dis[v][n]==dis[][n]) add(u,v,c);
if(dis[][v]+w+dis[u][n]==dis[][n]) add(v,u,c);//如果这条边在最短路上,就加到最短路图中
}
int ans=;
while(bfs())
{
while(int temp=dfs(,0x7fffffff))
ans+=temp;
}
printf("%d\n",ans); return ;
}
洛谷 P4300 BZOJ 1266 [AHOI2006]上学路线route的更多相关文章
- BZOJ 1266: [AHOI2006]上学路线route(最短路+最小割)
第一问最短路.第二问,先把最短路的图建出来(边(u,v)满足d[s->u]+d[v->t]+d(u,v)==最短路径长度,就在图中,可以从源点和汇点分别跑一次最短路得到每个点到源点和汇点的 ...
- bzoj 1266 [AHOI2006] 上学路线 route 题解
转载请注明:http://blog.csdn.net/jiangshibiao/article/details/23989499 [原题] 1266: [AHOI2006]上学路线route Time ...
- BZOJ 1266: [AHOI2006]上学路线route
题目描述 可可和卡卡家住合肥市的东郊,每天上学他们都要转车多次才能到达市区西端的学校.直到有一天他们两人参加了学校的信息学奥林匹克竞赛小组才发现每天上学的乘车路线不一定是最优的. 可可:"很 ...
- BZOJ 1266: [AHOI2006]上学路线route Floyd_最小割
十分简单的一道题. 图这么小,跑一边 Floyd 就得到第一问最短路径的答案. 考虑第二问怎么求:我们可以先将最短路径组成的图从原图中抽离出来,构成新图 $G$. 我们发现,只要 $G$ 的起点与终点 ...
- bzoj 1266 1266: [AHOI2006]上学路线route
1266: [AHOI2006]上学路线route Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 2356 Solved: 841[Submit][S ...
- [BZOJ 1266][AHOI2006]上学路线(最短路+最小割)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1266 分析: 很简单的题目,容易想到就是把所有的最短路径挑出来,然后在这个图里跑最小割 ...
- bzoj 1266 [AHOI2006] 上学路线
传送门 传说中的经典容斥+卢卡斯定理+中国剩余定理 题解传送门 //Achen #include<algorithm> #include<iostream> #include& ...
- bzoj1266 [AHOI2006]上学路线route floyd建出最短路图+最小割
1266: [AHOI2006]上学路线route Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 2490 Solved: 898[Submit][S ...
- bzoj1266 [AHOI2006]上学路线route floyd+最小割
1266: [AHOI2006]上学路线route Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 2490 Solved: 898[Submit][S ...
随机推荐
- Delphi XE2 之 FireMonkey 入门(14) - 滤镜: 概览
相关单元: FMX.Filter FMX.FilterCatBlur FMX.FilterCatGeometry FMX.FilterCatTransition FMX_FilterCatColor ...
- Model Inversion Attack Paper Indexpage
Paper [1]: White-box neural network attack, adversaries have full access to the model. Using Gradien ...
- String 和 new String()的区别
String 和 new String()的区别 For Example String str1 = "ABC" String str2 = new String("AB ...
- Vue 基础 day01
什么是Vue.js Vue.js 是目前最火的一个前端框架,React是最流行的一个前端框架(React除了开发网站,还可以开发手机App, Vue语法也是可以用于进行手机App开发的,需要借助于We ...
- Tunnel Warfare HDU 1540 区间合并+最大最小值
Tunnel Warfare HDU 1540 区间合并+最大最小值 题意 D x是破坏这个点,Q x是表示查询以x所在的最长的连续的点的个数,R是恢复上一次破坏的点. 题解思路 参考的大佬博客 这里 ...
- [BZOJ4476] [JSOI2015] 送礼物 (01分数规划+ST表)
[BZOJ4476] [JSOI2015] 送礼物 (01分数规划+ST表) 题面 给出n,k,l,r和序列a,要求从a中选一段连续的区间[i,j]出来,使得M(i,j)-m(i,j)/(j-i+k) ...
- C++对象构造时,构造函数运行时并不知道VT的存在
class A {public: A() { init(); } virtual void init() { printf("A::init\n"); }}; class B : ...
- 什么是dockerfile?
什么是dockerfile? Dockerfile是一个包含用于组合映像的命令的文本文档.可以使用在命令行中调用任何命令. Docker通过读取Dockerfile中的指令自动生成映像. docker ...
- JS中类或对象的定义说明
本篇文章主要是对JS中类或对象的定义进行说明介绍.我们知道,JS是面向对象的.谈到面向对象,就不可避免的要涉及类的概念.一般像c#,java这些强类型语言都有固定的定义类的语法.而JS的不同之处在于它 ...
- IMAP协议学习笔记(一)
IMAP IMAP(Internet Mail Access Protocol,Internet邮件访问协议)以前称作交互邮件访问协议(Interactive Mail Access Protocol ...