嘟嘟嘟

这道题他会卡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的更多相关文章

  1. [USACO11JAN]Roads and Planes G【缩点+Dij+拓补排序】

    题目 Farmer John正在一个新的销售区域对他的牛奶销售方案进行调查.他想把牛奶送到T个城镇 (1 <= T <= 25,000),编号为1T.这些城镇之间通过R条道路 (1 < ...

  2. P3008 [USACO11JAN]Roads and Planes G 拓扑排序+Dij

    题目描述 Farmer John正在一个新的销售区域对他的牛奶销售方案进行调查.他想把牛奶送到T个城镇 (1 <= T <= 25,000),编号为1T.这些城镇之间通过R条道路 (1 & ...

  3. 【图论】USACO11JAN Roads and Planes G

    题目内容 洛谷链接 Farmer John正在一个新的销售区域对他的牛奶销售方案进行调查.他想把牛奶送到\(T\)个城镇 (\(1 <= T <= 25,000\)),编号为\(1\)到\ ...

  4. P3008 [USACO11JAN]Roads and Planes G (最短路+拓扑排序)

    该最短路可不同于平时简单的最短路模板. 这道题一看就知道用SPFA,但是众所周知,USACO要卡spfa,所以要用更快的算法. 单向边不构成环,双向边都是非负的,所以可以将图分成若干个连通块(内部只有 ...

  5. P3008 [USACO11JAN]道路和飞机Roads and Planes

    P3008 [USACO11JAN]道路和飞机Roads and Planes Dijkstra+Tarjan 因为题目有特殊限制所以不用担心负权的问题 但是朴素的Dijkstra就算用堆优化,也显然 ...

  6. Luogu 3008 [USACO11JAN]道路和飞机Roads and Planes

    BZOJ2200 听说加上slf优化的spfa的卡过,真的不想写这些东西. 考虑使用堆优化的dij算法. 先加上所有双向边,然后dfs一下搜出所有由双向边构成的联通块,然后加上所有的单向边,一边对所有 ...

  7. 总结-一本通提高篇&算竞进阶记录

    当一个人看见星空,就再无法忍受黑暗 为了点亮渐渐沉寂的星空 不想就这样退役 一定不会鸽の坑 . 一本通提高篇 . 算竞进阶 . CDQ & 整体二分 . 平衡树 . LCT . 字符串 . 随 ...

  8. poj 1251 Jungle Roads (最小生成树)

    poj   1251  Jungle Roads  (最小生成树) Link: http://poj.org/problem?id=1251 Jungle Roads Time Limit: 1000 ...

  9. Jungle Roads[HDU1301]

    Jungle Roads Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tota ...

随机推荐

  1. Windbg 脚本命令简介 二, Windbg command

    Windbg  脚本命令简介 二, Windbg  script command $<, $><, $$<, $$><, $$>a< (Run Scri ...

  2. 前端(十二):react-redux实现逻辑

    一.context实现数据传递 在react中,props和state都可以设置数据.不同的是,props借助组件属性传递数据但不可以渲染组件,它相对来说是“静态的”:state可以监听事件来修改数据 ...

  3. Struts2 (三) — OGNL与值栈

    一.OGNL表达式 1.概述 1.1什么是OGNL ​ OGNL是Object-Graph Navigation Language的缩写,俗称对象图导航语言. 它是一种功能强大的表达式语言,通过它简单 ...

  4. Bookmarklet编写指南

    作者: 阮一峰 日期: 2011年6月11日 前一段日子,我写了两个Bookmarklet----"短网址生成"和"短网址还原". 它们用起来很方便,除了我本人 ...

  5. 【源代码R3】移植一份LARGE_INTEGER转时间的代码

    本代码来自ReactOS-0.4.0\lib\rtl\time.c中的函数RtlTimeToTimeFields(IN PLARGE_INTEGER Time, OUT PTIME_FIELDS Ti ...

  6. SPARK - Execute Framework

    Spark函数详解系列之RDD基本转换 https://www.cnblogs.com/MOBIN/p/5373256.html The  RDD provides low level API for ...

  7. Linux开篇

    1.为什么学习Linux? 2.学习Linux的资料

  8. Two ways to assign values to member variables

    setXxx()方法,带参数的构造方法.类名作为形式参数,其实里面需要传入一个该类的对象.类名作为返回值,其实返回的是一个该类的对象.

  9. C/C++标准有哪些?

                        1. C 时间 名称 标准制定组织 事件 1978 K&R标准 K&R <The C Programming Language>   ...

  10. Vue之自定义组件的v-model

    最近在学习vue,今天看到自定义事件的表单输入组件,纠结了一会会然后恍然大悟...官方教程写得不是很详细,所以我决定总结一下. v-model语法糖 v-model实现了表单输入的双向绑定,我们一般是 ...