P3008 [USACO11JAN]Roads and Planes G (最短路+拓扑排序)
该最短路可不同于平时简单的最短路模板。
这道题一看就知道用SPFA,但是众所周知,USACO要卡spfa,所以要用更快的算法。
单向边不构成环,双向边都是非负的,所以可以将图分成若干个连通块(内部只有双向边),用拓扑排序的框架处理整张图求解最短路,对于每个入度为0的连通块求一次最短路,因为边权非负,可以用dijkstra。
1 #include<bits/stdc++.h>
2 using namespace std;
3 const int N=25005,M=150005;
4 int head[N],to[M],nxt[M],edge[M],mark[M],tot;
5 int n,m,p,s,c[N],cnt,deg[N],d[N];
6 bool v[N];
7 queue<int> q;
8 vector<int> a[N];
9 priority_queue<pair<int,int> > heap;
10
11 void add(int x,int y,int z,int k){
12 nxt[++tot]=head[x];head[x]=tot;to[tot]=y;
13 mark[tot]=k;edge[tot]=z;
14 }
15
16 void dfs(int x){
17 c[x]=cnt;
18 a[cnt].push_back(x);
19 for(int i=head[x];i;i=nxt[i]){
20 if(mark[i]==1) continue;//单向边就跳过
21 int y=to[i];
22 if(!c[y]) dfs(y);
23 }
24 }
25
26 void dijkstra(int k){//算k这一块的最短路
27 for(int j=0;j<a[k].size();j++){//将块中每个点取出
28 int x=a[k][j];
29 heap.push(make_pair(-d[x],x));
30 }
31 while(!heap.empty()){
32 int x=heap.top().second;heap.pop();
33 if(v[x]) continue;
34 v[x]=1;
35 for(int i=head[x];i;i=nxt[i]){
36 int y=to[i];
37 if(mark[i]==0){
38 if(d[y]>d[x]+edge[i]){
39 d[y]=d[x]+edge[i];
40 heap.push(make_pair(-d[y],y));
41 }
42 }else{
43 d[y]=min(d[y],d[x]+edge[i]);
44 if(--deg[c[y]]==0) q.push(c[y]);//入度为0加入队列
45 }
46 }
47 }
48 }
49
50 int main(){
51 scanf("%d%d%d%d",&n,&m,&p,&s);
52 for(int i=1;i<=m;i++){
53 int x,y,z;
54 scanf("%d%d%d",&x,&y,&z);
55 add(x,y,z,0);
56 add(y,x,z,0);//双向边
57 }
58 for(int i=1;i<=p;i++){
59 int x,y,z;
60 scanf("%d%d%d",&x,&y,&z);
61 add(x,y,z,1);
62 }
63 for(int i=1;i<=n;i++){
64 if(c[i]==0){
65 cnt++;
66 dfs(i);
67 }
68 }
69 for(int x=1;x<=n;x++){//统计每个连通块总入度
70 for(int i=head[x];i;i=nxt[i]){
71 if(mark[i]==0) continue;
72 deg[c[to[i]]]++;
73 }
74 }
75 for(int i=1;i<=cnt;i++)//拓扑排序
76 if(!deg[i]) q.push(i);
77 memset(d,0x3f,sizeof(d));
78 d[s]=0;
79 while(!q.empty()){
80 int k=q.front();q.pop();//块号
81 dijkstra(k);
82 }
83 for(int i=1;i<=n;i++){
84 if(d[i]>n*10000) puts("NO PATH");
85 else printf("%d\n",d[i]);
86 }
87 }
P3008 [USACO11JAN]Roads and Planes G (最短路+拓扑排序)的更多相关文章
- 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\)到\ ...
- [USACO11JAN]Roads and Planes G【缩点+Dij+拓补排序】
题目 Farmer John正在一个新的销售区域对他的牛奶销售方案进行调查.他想把牛奶送到T个城镇 (1 <= T <= 25,000),编号为1T.这些城镇之间通过R条道路 (1 < ...
- [NOIP2017]逛公园 最短路+拓扑排序+dp
题目描述 给出一张 $n$ 个点 $m$ 条边的有向图,边权为非负整数.求满足路径长度小于等于 $1$ 到 $n$ 最短路 $+k$ 的 $1$ 到 $n$ 的路径条数模 $p$ ,如果有无数条则输出 ...
- [Luogu P3953] 逛公园 (最短路+拓扑排序+DP)
题面 传送门:https://www.luogu.org/problemnew/show/P3953 Solution 这是一道神题 首先,我们不妨想一下K=0,即求最短路方案数的部分分. 我们很容易 ...
- [USACO11JAN]Roads and Planes
嘟嘟嘟 这道题他会卡spfa,不过据说加SLF优化后能过,但还是讲讲正解吧. 题中有很关键的一句,就是无向边都是正的,只有单向边可能会有负的.当把整个图缩点后,有向边只会连接在每一个联通块之间(因为图 ...
- 【BZOJ5109】[CodePlus 2017]大吉大利,晚上吃鸡! 最短路+拓扑排序+DP
[BZOJ5109][CodePlus 2017]大吉大利,晚上吃鸡! Description 最近<绝地求生:大逃杀>风靡全球,皮皮和毛毛也迷上了这款游戏,他们经常组队玩这款游戏.在游戏 ...
- BZOJ1880:[SDOI2009]Elaxia的路线(最短路,拓扑排序)
Description 最近,Elaxia和w**的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间.Elaxia和w**每天都要奔波于宿舍和实验室之间, ...
- NOIP2017 Day1 T3 逛公园(最短路+拓扑排序+DP)
神tm比赛时多清个零就有60了T T 首先跑出1起点和n起点的最短路,因为k只有50,所以可以DP.设f[i][j]表示比最短路多走i的长度,到j的方案数. 我们发现如果在最短路上的和零边会有后向性, ...
随机推荐
- NOIP提高组模拟赛26
A. LCIS 蓝书原题,CF10D 弱化版 首先直接把 LIS 和 LCS 合起来设计一个 DP . 设 \(dp_{i,j}\) 表示 \(A_{1\dots i}\) 和 \(B_{1\dots ...
- 20170622日行一记之PHP函数
fread() 函数读取文件(可安全用于二进制文件) fread(file,length) 参数 描述 file 必需.规定要读取打开文件. length 必需.规定要读取的最大字节数. 该函数在读取 ...
- Python 懂车帝全车系销量排行榜
本文所有教程及源码.软件仅为技术研究.不涉及计算机信息系统功能的删除.修改.增加.干扰,更不会影响计算机信息系统的正常运行.不得将代码用于非法用途,如侵立删! Python 懂车帝全车系销量排行榜 需 ...
- 用好JAVA中的函数式接口,轻松从通用代码框架中剥离掉业务定制逻辑
大家好,又见面了. 今天我们一起聊一聊JAVA中的函数式接口.那我们首先要知道啥是函数式接口.它和JAVA中普通的接口有啥区别?其实函数式接口也是一个Interface类,是一种比较特殊的接口类,这个 ...
- Spring 01 概述
简介 Spring 是开源的轻量级 J2EE 框架 我们常说的 Spring 实际上是指 Spring Framework,它是 Spring 家族中的一个重要分支. 官方文档 https://doc ...
- 上传代码到GitHub仓库
上传代码到GitHub仓库 准备工作 意思是自从 21 年 8 月 13 后不再支持用户名密码的方式验证了,需要创建个人访问令牌(personal access token). 这里就不多说了 Git ...
- linux --stdin 管道 标准输入重定向
linux --stdin 标准输入重定向 --stdin This option is used to indicate that passwd should read the new passwo ...
- Atcoder Beginner Contest 200 E. Minflip Summation(概率数论)
题面 一个字符串 T T T 是由一个包含 0.1.? 的字符串 S S S 循环连接 K K K 次获得的. 字符串 T T T 中的每个 ? 都可以换成 0 或 1 ,假设 T T T 中一共有 ...
- 【LOJ#3197】【eJOI2019】T形覆盖 - (图论、简单推导)
题面 题解 (题目中说的四种摆放方式实际上是分别旋转0°,90°,180°,270°后的图形) 题目中关于摆放方式的描述听起来很臭,我们把它转换一下,每个拼版先覆盖"上下左右中"五 ...
- java方法---定义,调用
定义,调用 1.方法的定义 方法就是一段用来完成特定功能的代码片段,类似于其它语言的函数. 方法用于定义该类或该类的实例的行为特征和功能实现.方法是类和对象行为特征的抽象. 方法很类似于面向过程中的函 ...