【BZOJ2200】道路和航线(并查集,拓扑排序,最短路)
题意:n个点,有m1条双向边,m2条单向边,双向边边长非负,单向边可能为负
保证如果有一条从x到y的单项边,则不可能存在从y到x的路径
问从S出发到其他所有点的最短路
n<=25000,n1,m2<=5e4,边权绝对值<=1e4
思路:听说银川出10年前USACO的原题?
负权边不能直接dijkstra,SPFA又会TLE
考虑这题的特殊限制:双向边边长非负,单向边可能为负,保证如果有一条从x到y的单向边,则不可能存在从y到x的路径
由此可知如果把所有联通性相同的点缩成一个分量,则负权的单向边只可能在不同的分量之间出现,且无负环
用并查集维护分量,将分量拓扑排序,按分量的拓扑序依次将边和点加入,跑dijkstra
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<ll,ll> Pll;
typedef vector<int> VI;
typedef vector<PII> VII;
//typedef pair<ll,ll>P;
#define N 300010
#define M 200010
#define fi first
#define se second
#define MP make_pair
#define pb push_back
#define pi acos(-1)
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
#define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
#define lowbit(x) x&(-x)
#define Rand (rand()*(1<<16)+rand())
#define id(x) ((x)<=B?(x):m-n/(x)+1)
#define ls p<<1
#define rs p<<1|1 const //ll MOD=1e9+7,inv2=(MOD+1)/2;
double eps=1e-;
int INF=1e9;
int dx[]={-,,,};
int dy[]={,,-,}; struct edge
{
int x,y,z;
edge()=default;
edge(int x,int y,int z):x(x),y(y),z(z){}
}a[N],b[N]; vector<edge>c[N];
vector<int>p[N];
int head[N],vet[N],nxt[N],len[N],flag[N],s[N],num[N],dis[N],vis[N],f[N],d[N],q[N],
tot,id,n,m1,m2,S; int read()
{
int v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} void add(int a,int b,int c)
{
nxt[++tot]=head[a];
vet[tot]=b;
len[tot]=c;
head[a]=tot;
} int find(int k)
{
if(f[k]!=k) f[k]=find(f[k]);
return f[k];
} void topo()
{
rep(i,,n) f[i]=i;
rep(i,,m1)
{
int p=find(a[i].x),q=find(a[i].y);
if(p!=q) f[p]=q;
}
rep(i,,n) head[i]=d[i]=;
tot=;
rep(i,,m2)
{
int p=find(b[i].x),q=find(b[i].y);
if(p!=q)
{
d[q]++; add(p,q,);
}
}
int t=,w=;
id=;
rep(i,,n)
if(f[i]==i&&d[i]==){w++; q[w]=i;}
while(t<w)
{
t++;
int u=q[t];
s[u]=++id;
int e=head[u];
while(e)
{
int v=vet[e];
d[v]--;
if(d[v]==){w++; q[w]=v;}
e=nxt[e];
}
}
rep(i,,n)
{
num[i]=s[find(i)];
p[num[i]].pb(i);
} rep(i,,m1)
{
int x=num[a[i].x];
c[x].pb(edge(a[i].x,a[i].y,a[i].z));
c[x].pb(edge(a[i].y,a[i].x,a[i].z));
}
rep(i,,m2)
{
int x=num[b[i].x];
c[x].pb(edge(b[i].x,b[i].y,b[i].z));
} } void solve()
{
priority_queue<PII> q;
rep(i,,n) head[i]=vis[i]=;
tot=;
rep(i,,n) dis[i]=INF;
dis[S]=;
rep(i,,id)
{
for(int j=;j<p[i].size();j++)
{
int x=p[i][j];
q.push(MP(-dis[x],x));
}
for(int j=;j<c[i].size();j++)
{
int x=c[i][j].x,y=c[i][j].y,z=c[i][j].z;
add(x,y,z);
} while(!q.empty())
{
int u=q.top().se;
q.pop();
if(vis[u]) continue;
vis[u]=;
int e=head[u];
while(e)
{
int v=vet[e];
if(dis[u]+len[e]<dis[v])
{
dis[v]=dis[u]+len[e];
if(num[v]<=i) q.push(MP(-dis[v],v));
}
e=nxt[e];
}
}
}
rep(i,,n)
if(dis[i]>5e8) printf("NO PATH\n");
else printf("%d\n",dis[i]);
} int main()
{
n=read(),m1=read(),m2=read(),S=read();
rep(i,,m1) a[i].x=read(),a[i].y=read(),a[i].z=read();
rep(i,,m2) b[i].x=read(),b[i].y=read(),b[i].z=read();
topo();
solve();
return ;
}
【BZOJ2200】道路和航线(并查集,拓扑排序,最短路)的更多相关文章
- 并查集+拓扑排序 赛码 1009 Exploration
题目传送门 /* 题意:无向图和有向图的混合图判环: 官方题解:首先对于所有的无向边,我们使用并查集将两边的点并起来,若一条边未合并之前, 两端的点已经处于同一个集合了,那么说明必定存在可行的环(因为 ...
- HDU 1811:Rank of Tetris(并查集+拓扑排序)
http://acm.hdu.edu.cn/showproblem.php?pid=1811 Rank of Tetris Problem Description 自从Lele开发了Rating系 ...
- hdu 1811Rank of Tetris (并查集 + 拓扑排序)
/* 题意:这些信息可能有三种情况,分别是"A > B","A = B","A < B",分别表示A的Rating高于B,等于B ...
- 【并查集+拓扑排序】【HDU1811】【Rank of Tetris】
题意:给你3种关系 A=B,A>B,A<B 问是否排名方式唯一,或者存在矛盾 解 1.读入数据先处理 =号 用并查集的祖先作为代表元素,其他儿子节点都等于跟这个点重叠. 再读入 '< ...
- Codeforces Round #541 (Div. 2) D(并查集+拓扑排序) F (并查集)
D. Gourmet choice 链接:http://codeforces.com/contest/1131/problem/D 思路: = 的情况我们用并查集把他们扔到一个集合,然后根据 > ...
- Codeforces Round #541 (Div. 2) D 并查集 + 拓扑排序
https://codeforces.com/contest/1131/problem/D 题意 给你一个n*m二维偏序表,代表x[i]和y[j]的大小关系,根据表构造大小分别为n,m的x[],y[] ...
- HDU 1811 Rank of Tetris(并查集+拓扑排序 非常经典)
Rank of Tetris Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- HDU 1811(并查集+拓扑排序)题解
Problem Description 自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球.为了更好的符合那些爱好者的喜好,Lele又想了一个新点子:他 ...
- HDU 5222 ——Exploration——————【并查集+拓扑排序判有向环】
Exploration Time Limit: 30000/15000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)T ...
- HDU——1272小希的迷宫(并查集+拓扑排序)
小希的迷宫 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...
随机推荐
- psp周总结02
周日 周一 周二 周三 周四 周五 周六 所花时间 180 60 240 180 340 180 培训 代码量 186 65 157 86 200 200 博客量 1 1 了解的知识点 jsp页面 ...
- 多变量分析绘图(hue参数)以及盒图和小提琴图
1,函数stipplot() stipplot()函数用来画散点图,其x轴是离散型的变量 直接上代码 import seaborn as sns import numpy as np import p ...
- 重载Prometheus配置
发送SIGHUP信号给应用程序的主进程: pid ‘’-1‘’是指“终端断线” 发送post请求给指定端点: curl -XPOST http://ip:9090/-/reload 对于此种方法要注意 ...
- 五、Zabbix-自动注册
一.Zabbix Serber 1.进入动作界面 配置—>动作—>事件源—>自动注册—>创建动作 2.配置自动注册动作 1.配置动作 2.配置操作 Next step 添加成功 ...
- 第二周JAVA总结
学海无涯,在学习这件事情上得用点心了
- vue组件化编程应用
写几个小案例来理解vue的组件化编程思想,下面是一个demo. 效果图示: 功能: Add组件用于添加用户评论,提交后右边评论回复会立马显示数据.Item组件点击删除可以删除当前用户评论.当List组 ...
- centos 7 无网络情况下,解决yum 安装依赖rpm包
方法一:在一台有网络的机器,用yum下载好所需程序,传到另外一台网络的机器上安装 yum install xtrabackup --downloadonly --downloaddir=/rpmpat ...
- PCIeのType0与Type1型配置请求与BAR(基地址寄存器)
PCIe中存在两种配置空间Type0&type1,TYPE0对应非桥设备(Endpoint),Type1对应桥设备(Root和Switch端口中的P2P桥)因为Root每个端口总都含有一个P2 ...
- 该项目不知道如何运行配置文件 IIS Express。The project doesn’t know how to run the profile IIS Express
原文:该项目不知道如何运行配置文件 IIS Express. 方案1(推荐). 可能原因是:禁用掉Microsft ASP.NET和Web工具扩展和微软Azure的应用程序服务工具扩展,恢复启用即可. ...
- vuex介绍和vuex数据传输流程
1.什么是vuex? 公共状态管理:解决多个非父子组件传值麻烦的问题:简单说就是多个页面都能用Vuex中store公共的数据 a.并不是所有的数据都要放在Vuex中,只有各个组件公用的一些数据会放在V ...