[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 ...
随机推荐
- 删除Panl控件中窗体的方法
//删除窗体方法 private void CloseFrm() { foreach (Control item in panel1.Controls) { if (item is Form) //判 ...
- spss C# 二次开发 学习笔记(六)——Spss统计结果的输出
Spss的二次开发可以很简单,实例化一个对象,然后启用服务,接着提交命令,最后停止服务. 其中重点为提交命令,针对各种统计功能需求,以及被统计分析的数据内容等,命令的内容可以很复杂,但也可以简单的为一 ...
- 关于JAVA项目报表选型过程
本人一直在走.NET技术路线,考虑到后期公司搞JAVA项目,也算是进行技术灾备,开始对JAVA技术进行关注.万事开头难,也是上来一头包.没办法,顶着上吧.上面开始分给我任务了.就是对后期项目报表进行方 ...
- 《JavaWeb从入门到改行》关于BaseServlet那些事
@为什么需要BaseServlet? 我们知道一个POST或者GET提交对应着一个Servlet, 无数的提交会让Servlet页面增加,我们希望一个Servlet就能处理很多提交的请求. @Bas ...
- JS判断两个数是否能除尽
function judgeDivisor(m, n) { var num = {}; var i = 0; var x = parseInt(m / n); m = m % n; var resul ...
- COCI2017-2018-2 San
题意 有\(n \leq 40\)个节点,每个节点有权值\(H \leq 1e9\)和贡献\(v \leq 1e9\),从任意一个点可以向右跳到一个权值不小于它的节点,并获得该点贡献 可以从任意一个点 ...
- Bootstrap 在线引用
Bootstrap 3.3.0 js 文件 <script src="http://cdn.bootcss.com/bootstrap/3.3.0/js/bootstrap.min.j ...
- maven(12),排除冲突JAR包
JAR包冲突 <dependencies> <dependency> <groupId>org.springframework</groupId> ...
- 哪个HTML5内建对象用于在画布上绘制?()
哪个HTML5内建对象用于在画布上绘制?() getContent getContext getGraphics getCanvas 我的理解: A.C.D不存在HTML5,,js方法中 HTML 5 ...
- OS考研复习笔记——操作系统的定义、目标、作用和发展的主要动力
计算机系统由硬件和软件两部分组成.操作系统(OS,Operating System)是配置在计算机硬件上的第一层软件,是对硬件系统的首次补充. 硬件:计算机物理设备,即各种处理机存储器.输入/输出设备 ...