BZOJ1266 [AHOI2006]上学路线
Description
Input
Output
Sample Input
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
Sample Output
5
HINT
2<=N<=500, 1<=M<=124 750, 1<=ti, ci<=10 000
合肥市的公交网络十分发达,你可以认为任意两个车站间都可以通过直达或转车互相到达,当然如果在你提供的删除方案中,家和学校无法互相到达,那么则认为上学需要的最短为正无穷大:这显然是一个合法的方案。
题解
首先Dijkstra求出起点到所有点的距离$dis_i$,然后我们发现当前影响最短路长度的边只有$dis_{q_i}=dis_{p_i}+t_i$的边,将保留这些边,求最小割即可。
附代码:
#include <algorithm>
#include <cstdio>
#include <queue>
typedef long long LL;
const LL INF = 1000000000000000LL;
const int N = 550;
const int M = 300000;
int pre[N], nxt[M], to[M], t[M], c[M], cnt = 0;
inline void addedge(int p, int q, int ti, int ci) {
to[cnt] = q; t[cnt] = ti; c[cnt] = ci;
nxt[cnt] = pre[p]; pre[p] = cnt++;
to[cnt] = p; t[cnt] = ti; c[cnt] = ci;
nxt[cnt] = pre[q]; pre[q] = cnt++;
}
LL dis[N];
int n, m;
struct HeapNode{
int x;
LL d;
HeapNode(int x = 0, LL d = 0) : x(x), d(d) {}
inline bool operator<(const HeapNode &y)const{
return d > y.d;
}
};
void Dijkstra() {
static std::priority_queue<HeapNode> Q;
std::fill(dis + 1, dis + n + 1, INF);
while (!Q.empty()) Q.pop();
Q.push(HeapNode(1, dis[1] = 0));
while (!Q.empty()) {
HeapNode x = Q.top(); Q.pop();
if (x.d != dis[x.x]) continue;
int u = x.x;
if (u == n) return;
for (int i = pre[u]; ~i; i = nxt[i])
if (dis[to[i]] > dis[u] + t[i])
Q.push(HeapNode(to[i], dis[to[i]] = dis[u] + t[i]));
}
}
struct Dinic{
int pre[N], nxt[M], to[M], cnt;
LL ret[M];
int dis[N];
Dinic() {
cnt = 0;
std::fill(pre, pre + N, -1);
}
inline void addedge(int p, int q, LL c) {
to[cnt] = q; ret[cnt] = c;
nxt[cnt] = pre[p]; pre[p] = cnt++;
to[cnt] = p; ret[cnt] = 0;
nxt[cnt] = pre[q]; pre[q] = cnt++;
}
bool BFS() {
static std::queue<int> Q;
while (!Q.empty()) Q.pop();
std::fill(dis + 1, dis + n + 1, -1);
dis[1] = 0;
Q.push(1);
while (!Q.empty()) {
int x = Q.front(); Q.pop();
for (int i = pre[x]; ~i; i = nxt[i])
if (ret[i] && !~dis[to[i]]) {
dis[to[i]] = dis[x] + 1;
Q.push(to[i]);
if (to[i] == n) return true;
}
}
return false;
}
LL DFS(int x, LL f) {
if (x == n) return f;
LL ans = 0;
for (int i = pre[x]; ~i && f; i = nxt[i])
if (ret[i] && dis[to[i]] == dis[x] + 1) {
LL df = DFS(to[i], std::min(f - ans, ret[i]));
ans += df;
ret[i] -= df; ret[i ^ 1] += df;
}
if (ans == f) dis[x] = n + 2;
return ans;
}
LL solve() {
LL ans = 0;
while (BFS()) ans += DFS(1, INF);
return ans;
}
};
Dinic solver;
int main() {
scanf("%d%d", &n, &m);
std::fill(pre + 1, pre + n + 1, -1);
int p, q, ti, ci;
for (int i = 0; i < m; ++i) {
scanf("%d%d%d%d", &p, &q, &ti, &ci);
addedge(p, q, ti, ci);
}
Dijkstra();
for (int i = 0; i < cnt; ++i)
if (dis[to[i]] - dis[to[i ^ 1]] == t[i])
solver.addedge(to[i ^ 1], to[i], c[i]);
printf("%lld\n%lld\n", dis[n], solver.solve());
return 0;
}
BZOJ1266 [AHOI2006]上学路线的更多相关文章
- 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 ...
- BZOJ1266 AHOI2006上学路线(最短路+最小割)
求出最短路后找出可能在最短路上的边,显然割完边后我们需要让图中这样的边无法构成1到n的路径,最小割即可,非常板子. #include<iostream> #include<cstdi ...
- BZOJ1266 [AHOI2006]上学路线route Floyd 最小割 SAP
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1266 题意概括 一个无向图,第一问:从1~n的最短路. 第二问,删除价值总和最小的边,使得1~n的 ...
- bzoj1266: [AHOI2006]上学路线route
最短路+最小割 首先如何使最短路变长?就是要每一条最短路都割一条边. 我们求出每个点到点1和点n的距离,就可以知道哪些边在最短路上(一开始没有想到求到0和n的距离,想用floyd,但是n=500,怕超 ...
- 【最短路】【spfa】【最小割】【Dinic】bzoj1266 [AHOI2006]上学路线route
原问题等价于断掉一些边,让原来所有的最短路全都无法联通S和T. 先求最短路,然后把在最短路上的边(dis[u[i]]+w[i]==dis[v[i]])加入新图里,跑最小割.显然. 注意是无向图. #i ...
- 【BZOJ1266】[AHOI2006]上学路线route Floyd+最小割
[BZOJ1266][AHOI2006]上学路线route Description 可可和卡卡家住合肥市的东郊,每天上学他们都要转车多次才能到达市区西端的学校.直到有一天他们两人参加了学校的信息学奥林 ...
- BZOJ 1266: [AHOI2006]上学路线route(最短路+最小割)
第一问最短路.第二问,先把最短路的图建出来(边(u,v)满足d[s->u]+d[v->t]+d(u,v)==最短路径长度,就在图中,可以从源点和汇点分别跑一次最短路得到每个点到源点和汇点的 ...
- BZOJ_1266_[AHOI2006]上学路线route_最小割
BZOJ_1266_[AHOI2006]上学路线route_最小割 Description 可可和卡卡家住合肥市的东郊,每天上学他们都要转车多次才能到达市区西端的学校.直到有一天他们两人参加了学校的信 ...
随机推荐
- 论文笔记:CNN经典结构2(WideResNet,FractalNet,DenseNet,ResNeXt,DPN,SENet)
前言 在论文笔记:CNN经典结构1中主要讲了2012-2015年的一些经典CNN结构.本文主要讲解2016-2017年的一些经典CNN结构. CIFAR和SVHN上,DenseNet-BC优于ResN ...
- linux C API连接并查询mysql5.7.9
开发环境: ubuntu16.04 mysql5.7.9 原生C API VIM 配置远程连接 配置mysql允许远程连接的方法默认情况下,mysql只允许本地登录,如果要开启远程连接,则需要修改/e ...
- js 封装trim()方法,去掉空格
<script> //定义一个对象 - 名字是$ var $$ = function() {}; //原型 $$.prototype = { $id:function(id) { retu ...
- Github概念理解备忘录
总结: add就是用来建立跟踪,添加文件到缓存区: commit就是把文件缓存区的文件正式加到本地库中: push就是把本地库更新到远程库中: git命令的操作要在仓库所在目录下进行才有效: 在Git ...
- 【算法笔记】B1052 卖个萌
题目链接:https://pintia.cn/problem-sets/994805260223102976/problems/994805273883951104 #include <math ...
- shiro学习笔记_0600_自定义realm实现授权
博客shiro学习笔记_0400_自定义Realm实现身份认证 介绍了认证,这里介绍授权. 1,仅仅通过配置文件来指定权限不够灵活且不方便.在实际的应用中大多数情况下都是将用户信息,角色信息,权限信息 ...
- Pycharm的配置和使用
pycharm pycharm是一个比较好的python IDE,可以在MACOS和windows上使用,补全功能强大,而且界面十分友好,特别适合python编程人员使用. pycharm Pycha ...
- Cloudera Manager安装之利用parcels方式(在线或离线)安装3或4节点集群(包含最新稳定版本或指定版本的安装)(添加服务)(Ubuntu14.04)(五)
前期博客 Cloudera Manager安装之Cloudera Manager 5.6.X安装(tar方式.rpm方式和yum方式) (Ubuntu14.04) (三) 如果大家,在启动的时候,比如 ...
- git 学习之基本概念
在学习 Git 的时候我们经常会听到工作区,版本库,暂存区.那么这些东西指的是什么呢?本次我们就一起学习一下. 工作区 顾名思义:工作的区域,那么你一般在哪工作呢?当然是你本地可以看到的目录啦! 版本 ...
- HDU 6187 Destroy Walls
Destroy Walls Long times ago, there are beautiful historic walls in the city. These walls divide the ...