[USACO11JAN]Roads and Planes
这道题他会卡spfa,不过据说加SLF优化后能过,但还是讲讲正解吧。
题中有很关键的一句,就是无向边都是正的,只有单向边可能会有负的。当把整个图缩点后,有向边只会连接在每一个联通块之间(因为图中没有环),而且缩点后的图一定是一个DAG,DAG的最短路就可以拓扑排序后直接求出最短路。
因此,对于每一个联通块内,我们可以dijkstra跑最短路:除了常规的更新以外,每一次跑的时候都要先把这个块内的所有点都放进优先队列中,因为有的点可能已经从别的联通块更新了。然后对于一条边u->v,如果u,v在一个联通块内,就正常更新,否则是更新dis[y],不把他放进队列,而是把y所在的联通块的入度--,如果为0,就放进拓扑序的队列中。
直到拓扑序的队列空。
对于有些走不到的点,可能在INF上加上了一个负数,因此最后判断是否能走到不能dis[i] = INF?,我就是稍微把这个上界放小一点,但又大于最远的dis,于是判断dis[i] > INF / 2?。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a) memset(a, 0, sizeof(a))
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-;
const int maxn = 2.5e4 + ;
inline ll read()
{
ll ans = ;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) {last = ch; ch = getchar();}
while(isdigit(ch)) {ans = ans * + ch - ''; ch = getchar();}
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < ) x = -x, putchar('-');
if(x >= ) write(x / );
putchar(x % + '');
} int n, r, p, s;
vector<int> v[maxn], c[maxn];
vector<int> blo[maxn]; int col[maxn], cnt = ;
void dfs(int now)
{
col[now] = cnt; blo[cnt].push_back(now);
for(int i = ; i < (int)v[now].size(); ++i)
if(!col[v[now][i]]) dfs(v[now][i]);
} int in[maxn];
queue<int> topo; #define pr pair<int, int>
#define mp make_pair
int dis[maxn];
bool inq[maxn];
void dijkstra(int bl)
{
Mem(inq);
priority_queue<pr, vector<pr>, greater<pr> > q;
for(int i = ; i < (int)blo[bl].size(); ++i) q.push(mp(dis[blo[bl][i]], blo[bl][i]));
while(!q.empty())
{
int now = q.top().second; q.pop();
if(inq[now]) continue;
inq[now] = ;
for(int i = ; i < (int)v[now].size(); ++i)
{
int to = v[now][i];
if(col[now] == col[to])
{
if(dis[to] > dis[now] + c[now][i])
{
dis[to] = dis[now] + c[now][i];
q.push(mp(dis[to], to));
}
}
else
{
if(dis[to] > dis[now] + c[now][i]) dis[to] = dis[now] + c[now][i];
if(!--in[col[to]]) topo.push(col[to]);
}
}
}
} int main()
{
n = read(); r = read(); p = read(); s = read();
for(int i = ; i <= r; ++i)
{
int x = read(), y = read(), co = read();
v[x].push_back(y); c[x].push_back(co);
v[y].push_back(x); c[y].push_back(co);
}
for(int i = ; i <= n; ++i) if(!col[i]) ++cnt, dfs(i);
for(int i = ; i <= p; ++i)
{
int x = read(), y = read(), co = read();
v[x].push_back(y); c[x].push_back(co);
if(col[x] != col[y]) in[col[y]]++;
}
for(int i = ; i <= cnt; ++i) if(!in[i]) topo.push(i);
for(int i = ; i <= n; ++i) dis[i] = INF; dis[s] = ;
while(!topo.empty()) dijkstra(topo.front()), topo.pop();
for(int i = ; i <= n; ++i) dis[i] > (INF >> ) ? printf("NO PATH\n") : (write(dis[i]), enter);
return ;
}
[USACO11JAN]Roads and Planes的更多相关文章
- [USACO11JAN]Roads and Planes G【缩点+Dij+拓补排序】
题目 Farmer John正在一个新的销售区域对他的牛奶销售方案进行调查.他想把牛奶送到T个城镇 (1 <= T <= 25,000),编号为1T.这些城镇之间通过R条道路 (1 < ...
- P3008 [USACO11JAN]Roads and Planes G 拓扑排序+Dij
题目描述 Farmer John正在一个新的销售区域对他的牛奶销售方案进行调查.他想把牛奶送到T个城镇 (1 <= T <= 25,000),编号为1T.这些城镇之间通过R条道路 (1 & ...
- 【图论】USACO11JAN Roads and Planes G
题目内容 洛谷链接 Farmer John正在一个新的销售区域对他的牛奶销售方案进行调查.他想把牛奶送到\(T\)个城镇 (\(1 <= T <= 25,000\)),编号为\(1\)到\ ...
- P3008 [USACO11JAN]Roads and Planes G (最短路+拓扑排序)
该最短路可不同于平时简单的最短路模板. 这道题一看就知道用SPFA,但是众所周知,USACO要卡spfa,所以要用更快的算法. 单向边不构成环,双向边都是非负的,所以可以将图分成若干个连通块(内部只有 ...
- P3008 [USACO11JAN]道路和飞机Roads and Planes
P3008 [USACO11JAN]道路和飞机Roads and Planes Dijkstra+Tarjan 因为题目有特殊限制所以不用担心负权的问题 但是朴素的Dijkstra就算用堆优化,也显然 ...
- Luogu 3008 [USACO11JAN]道路和飞机Roads and Planes
BZOJ2200 听说加上slf优化的spfa的卡过,真的不想写这些东西. 考虑使用堆优化的dij算法. 先加上所有双向边,然后dfs一下搜出所有由双向边构成的联通块,然后加上所有的单向边,一边对所有 ...
- 总结-一本通提高篇&算竞进阶记录
当一个人看见星空,就再无法忍受黑暗 为了点亮渐渐沉寂的星空 不想就这样退役 一定不会鸽の坑 . 一本通提高篇 . 算竞进阶 . CDQ & 整体二分 . 平衡树 . LCT . 字符串 . 随 ...
- poj 1251 Jungle Roads (最小生成树)
poj 1251 Jungle Roads (最小生成树) Link: http://poj.org/problem?id=1251 Jungle Roads Time Limit: 1000 ...
- Jungle Roads[HDU1301]
Jungle Roads Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tota ...
随机推荐
- 数据适配 DataAdapter对象
DataAdapter对象是DataSet和数据源之间的桥梁,可以建立并初始化数据表(即DataTable) 对数据源执行SQL指令,与DataSet对象结合,提供DataSet对象存取数据,可视为D ...
- c#参数修饰符-params
先来理解一下理论知识 params可以设置使用长度可变的参数. 使用要求: 1.在一个方法声明的参数中,只能有一个params修饰符,且被修饰的参数之后不能有其他参数(这一点就像“可选参数必须在必选参 ...
- linux的环境变量与文件查找
1. 环境变量 1.1 变量 shell 中的变量有不同类型,可参与运算,有作用域限定 变量的作用域即变量的有效范围(比如一个函数中.一个源文件中或者全局范围),在该范围内只能有一个同名变量.一旦离开 ...
- UVA1584(环状序列)
对于序列的最小值,可以定义一个比较的方法,然后用一般找最小值的方法遍历一遍即可 #include <iostream> #include <string> #include & ...
- UOJ169. 【UR #11】元旦老人与数列
传送门 考虑用 \(segment~tree~beats\) 那一套理论,维护区间最小值 \(mn\) 和严格次小值 \(se\) 那么可以直接 \(mlog^2n\) 维护前三个操作 考虑维护历史最 ...
- HDU P2089
题目大意为,统计区间内不含4和62的数字的个数: 老实说,看到这题我是抵触的..... 基本上是数位DP的板子,话说数位DP好像全是模板题吧: 预处理,有关的整区间的数字个数: 调用已有的区间,求解0 ...
- 相比之前其他几个入门的, 推荐: 简单vue2 入门教程
注意:Vue.js 不支持 IE8 及其以下 IE 版本. 具体可以看下 http://www.runoob.com/vue2/vue-tutorial.html 以下是学习过程 Vue ...
- 微服务架构之spring cloud feign
在spring cloud ribbon中我们用RestTemplate实现了服务调用,可以看到我们还是需要配置服务名称,调用的方法 等等,其实spring cloud提供了更优雅的服务调用方式,就是 ...
- Heap memory compared to stack memory
- Android解析WindowManagerService(一)WMS的诞生
前言 此前我用多篇文章介绍了WindowManager,这个系列我们来介绍WindowManager的管理者WMS,首先我们先来学习WMS是如何产生的.本文源码基于Android 8.0,与Andro ...