嘟嘟嘟

这道题他会卡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. forms身份认证仍然能访问html页面解决办法

    asp.net的forms身份认证保护是一个非常棒的东西,用VS2010创建一个Web应用程序即可看到范例 在web.config中配置 <authentication mode="F ...

  2. C# DateTime类型和sqlserver DateTime精度不同

    在最近的项目中, 有个关于时间的功能.一个请假的时间.前端选择的时候只有日期.所以比如请一天假就是选2017-8-15和2017-8-15,这样算请这一天的假.但是后台存入数据库时我不能就存2017- ...

  3. Java学习--Jsp简介

  4. 撩课-Mysql详解第3部分sql分类

    学习地址:[撩课-JavaWeb系列1之基础语法-前端基础][撩课-JavaWeb系列2之XML][撩课-JavaWeb系列3之MySQL][撩课-JavaWeb系列4之JDBC][撩课-JavaWe ...

  5. 一图解析 React组件生命周期 (React Component Lifecycle)

     React LifeCycle v1 参考官方文档作成 可放大  参考:https://reactjs.org/docs/react-component.html 数字补丁数字补丁数字补丁数字补丁数 ...

  6. poj 3104 dring 二分

    Drying Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7684   Accepted: 1967 Descriptio ...

  7. 使用NOPI读取Word、Excel文档内容

    使用NOPI读取Excel的例子很多,读取Word的例子不多. Excel的解析方式有多中,可以使用ODBC查询,把Excel作为一个数据集对待.也可以使用文档结构模型的方式进行解析,即解析Workb ...

  8. Oracle数据库基本操作 (六) —— 数据的导出与导入

    一.cmd 下登录oracle数据库下的指定用户 方式一:命令行明文连接登录 打开cmd,输入:sqlplus/nolog 输入:conn username/passworld@数据库实例名 方式二: ...

  9. Code Signal_练习题_palindromeRearranging

    Given a string, find out if its characters can be rearranged to form a palindrome. Example For input ...

  10. javascript函数中with的介绍

    /*js函数中with函数的用法分析定义 方便用来引用某个对象中已有的属性但是不能用来给对象添加属性 要给对象创建新的属性 必须明确的引用该对象*/代码格式with(object) statement ...