2019ICPC(银川) - Delivery Route(强连通分量 + 拓扑排序 + dijkstra)
题目:有n个派送点,x条双向边,y条单向边,出发点是s,双向边的权值均为正,单向边的权值可以为负数,对于单向边给出了一个限制:如果u->v成立,则v->u一定不成立。问,从s出发,到其他所有点的最短路是多少(包括s)。
思路:对于单向边的限制,我们可以这么理解:双向边相连接的点一定组成一个强连通分量,如果一条单向边存在于某个强连通分量中,可以得出:如果“u -> v”,则一定“v -> u”,可以推出单向边一定只存在于连接两个强连通分量,且还可以推出,强连通分量缩点后,连上单向边,此时的图一定是一个有向无环图,于是给出的限制"对于单向边给出了一个限制:如果u->v成立,则v->u一定不成立。"完全成立,于是图的性质我们分析完了。
①似乎这个图的性质可以直接跑dijkstra,的确可以,但是负权边的存在复杂度太大。
②每个强连通分量都可以dijkstra,且图存在拓扑排序,不如让入度为0的缩点先跑dijkstra,然后一条单向边只影响其他强连通分量的一个点的距离,然后按照拓扑序来确定每个强连通分量跑dijkstra的顺序。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue> #define ll long long
#define pb push_back
#define fi first
#define se second using namespace std; const int N = + ;
const int M = + ;
const ll INF = 1e10;
struct Edge{
int to, nxt, w;
}e[M << ];
struct node{
int u, v, w;
};
struct tmp{
int now;
ll w;
bool friend operator<(const tmp& a, const tmp& b){
return a.w > b.w;
}
};
int head[N], scc[N], du[N], vis[N], ok[N];
ll dis[N];
vector<node > vp[N];//单向边
vector<int > belong[N];//属于哪个scc
vector<int > mp[N];//存边
priority_queue<tmp > pque;
int n, x, y, s, tot, col; inline void add(int u, int v, int w){
e[tot].to = v; e[tot].nxt = head[u];
e[tot].w = w; head[u] = tot++;
} //缩点
void dfs(int now){
scc[now] = col;
belong[col].pb(now);
for(int o = head[now]; ~o; o = e[o].nxt)
if(!scc[e[o].to]) dfs(e[o].to);
} //检测这个点是不是有效点
void check(int now){
ok[now] = ;
for(auto to : mp[now])
if(!ok[to]) check(to);
} void dijkstra(int ss){
while(!pque.empty()) pque.pop();
if(ss == s) pque.push({ss, dis[ss]}); //图一定是从出发点s开始的
else{
//相当于从一个超级源点出发
for(auto it : belong[scc[ss]]) pque.push({it, dis[it]});
}
while(!pque.empty()){
int u = pque.top().now;
pque.pop();
if(vis[u]) continue;
vis[u] = ;
for(int o = head[u]; ~o; o = e[o].nxt){
if(dis[u] + e[o].w < dis[e[o].to]){
dis[e[o].to] = dis[u] + e[o].w;
pque.push({e[o].to, dis[e[o].to]});
}
}
}
} void top_sort(){
queue<int > que;
que.push(scc[s]);//满足的图 应该是从s的连通图出发的拓扑图
dijkstra(s);
while(!que.empty()){
int inx = que.front();
que.pop();
for(auto it : vp[inx]){
//一条单向边影响一个点的距离
if(dis[it.u] + it.w < dis[it.v]){
dis[it.v] = dis[it.u] + it.w;
}
//入度0,跑dijkstra
if(--du[scc[it.v]] == ){
que.push(scc[it.v]);
dijkstra(it.v);
}
}
}
} void solve(){
scanf("%d%d%d%d", &n, &x, &y, &s);
for(int i = ; i <= n; ++i) head[i] = -; tot = ;
for(int i = ; i <= n; ++i) dis[i] = INF; dis[s] = ;
int u, v, w;
for(int i = ; i <= x; ++i){
scanf("%d%d%d", &u, &v, &w);
add(u, v, w); add(v, u, w);
mp[u].pb(v); mp[v].pb(u);
} vector<node > tmp;
for(int i = ; i <= y; ++i){
scanf("%d%d%d", &u, &v, &w);
tmp.pb({u, v, w});
mp[u].pb(v);
}
//图一定是从出发点s开始的,所以从s出发遍历图,无法到达的点,就是无法到达的点
//检测这个点是不是有效点
check(s);
//缩点
for(int i = ; i <= n; ++i){
if(!scc[i] && ok[i]){
++col;
dfs(i);
}
}
//入度统计
for(auto x : tmp){
if(ok[x.u] && ok[x.v]){//有效点
vp[scc[x.u]].pb(x);
++du[scc[x.v]];
}
}
top_sort();//拓扑序
for(int i = ; i <= n; ++i){
if(dis[i] == INF) printf("NO PATH\n");
else printf("%lld\n", dis[i]);
}
} int main(){ solve(); return ;
} /*
7 5 3 4
1 2 5
3 4 5
5 6 10
5 7 4
6 7 105
3 5 -100
4 6 -100
7 2 -100
*/
2019ICPC(银川) - Delivery Route(强连通分量 + 拓扑排序 + dijkstra)的更多相关文章
- BZOJ_3887_[Usaco2015 Jan]Grass Cownoisseur_强连通分量+拓扑排序+DP
BZOJ_3887_[Usaco2015 Jan]Grass Cownoisseur_强连通分量+拓扑排序+DP Description In an effort to better manage t ...
- BZOJ_2208_[Jsoi2010]连通数_强连通分量+拓扑排序+手写bitset
BZOJ_2208_[Jsoi2010]连通数_强连通分量+拓扑排序+手写bitset Description Input 输入数据第一行是图顶点的数量,一个正整数N. 接下来N行,每行N个字符.第i ...
- poj 2762(强连通分量+拓扑排序)
题目链接:http://poj.org/problem?id=2762 题意:给出一个有向图,判断任意的两个顶点(u,v)能否从u到达v,或v到达u,即单连通,输出Yes或No. 分析:对于同一个强连 ...
- BZOJ1924:[SDOI2010]所驼门王的宝藏(强连通分量,拓扑排序)
Description Input 第一行给出三个正整数 N, R, C. 以下 N 行,每行给出一扇传送门的信息,包含三个正整数xi, yi, Ti,表示该传送门设在位于第 xi行第yi列的藏宝宫室 ...
- CDOJ 图论专题 A.不是图论 强连通分量+拓扑排序 经典
题目链接 在其中纠错第一次wa代码 #include <cstdio> #include <cstring> #include <cstdlib> #includ ...
- POJ 2762 Going from u to v or from v to u?(强连通分量+拓扑排序)
职务地址:id=2762">POJ 2762 先缩小点.进而推断网络拓扑结构是否每个号码1(排序我是想不出来这点的. .. ).由于假如有一层为2的话,那么从此之后这两个岔路的点就不可 ...
- hihoCoder #1185 : 连通性·三(强联通分量+拓扑排序)
#1185 : 连通性·三 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 暑假到了!!小Hi和小Ho为了体验生活,来到了住在大草原的约翰家.今天一大早,约翰因为有事要出 ...
- POJ-2762-Going from u to v or from v to u(强连通, 拓扑排序)
链接: https://vjudge.net/problem/POJ-2762 题意: In order to make their sons brave, Jiajia and Wind take ...
- poj 2186 "Popular Cows"(强连通分量入门题)
传送门 参考资料: [1]:挑战程序设计竞赛 题意: 每头牛都想成为牛群中的红人. 给定N头牛的牛群和M个有序对(A, B),(A, B)表示牛A认为牛B是红人: 该关系具有传递性,所以如果牛A认为牛 ...
随机推荐
- java爬虫-妹子图
一,分析 1.选择入口 打开 https://www.mzitu.com/ 主页,我们发现主页有200+页图片,我们如果从首页入手,这里可能不是全部图片.这里我们打开每日更新 https://ww ...
- PHP5.6.23+Apache2.4.20+Eclipse for PHP 4.5开发环境配置
一.Apache配置(以httpd-2.4.20-x64-vc14.zip为例)(http://www.apachelounge.com/download/) 1.安装运行库vc11和vc14 2.解 ...
- 阿里云Tomcat配置
阿里云Tomcat配置并开放 本文可对以下问题提供参考 服务器 如何配置 Tomcat 配置 端口在监听,但是外网无法访问怎么办 注意事项: 对于阿里云服务器相对较为特殊,因为阿里云服务器除了需要在系 ...
- 05 JPAUtil工具类
public final class JPAUtil { // JPA的实体管理器工厂:相当于Hibernate的SessionFactory private static EntityManager ...
- utuntu sever1804显示中文putty可以输入中文
默认情况下,putty连接ubuntu server以后,哪怕设置的Utf-8的连接,也是无法显示中文的. 应该是ubuntu服务器端,没有字库的问题. 如果在putty显示和输入中文呢,因为配置信息 ...
- libra共识算法分析
核心算法说明 基于chained实现,整体上是当前轮推动下一轮共识继续下去, 如此来持续运转下去, 数据有效性证明基于(QC)实现 leader广播proposal消息{round, qc, p ...
- Mac上Burpsuite 拦截不到HTTPS流量怎么设置
在百度了一堆以及修修改改下终于拦截到HTTPS流量了. 安装步骤就大致讲一下吧 网上下载burp的安装包,然后Mac上直接打开这个burpUnlimited.jar包就可以了 我直接选择的第一个 ...
- 浅谈静态布局、流式布局,rem布局,弹性布局、响应式布局
静态布局: 特点:没有兼容性问题 PC:居中布局,所有样式使用绝对宽度/高度(px),设计一个Layout,在屏幕宽高有调整时,使用横向和竖向的滚动条来查阅被遮掩部分:移动设备:另外建立移动网站,单独 ...
- typescript package.json vscode 终端 运行任务 Ctrl shift B
{ "dependencies": { "typescript": "^3.6.4" } }
- Flask 之分析线程和协程
目录 flask之分析线程和协程 01 思考:每个请求之间的关系 02 threading.local 03 通过字典自定义threading.local 04 通过setattr和getattr实现 ...