【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 ...
随机推荐
- vue-devtools安装以后,勾选了“允许访问文件网址”之后还是无法使用
勾选了“允许访问文件网址”,还是无法使用: Vue.js is detected on this page. Devtools inspection is not available because ...
- 多线程14-Barrier
, b => Console.WriteLine()); ; i <= ; i++) { Console.Write ...
- Oracle 修改数据文件路径的方法
1. 关闭数据库,然后启动至mount状态 sqlplus / as sysdba shutdown immediate startup mount 2. 修改物理文件: 我这边将: c:\cwd ...
- 【监控笔记】【1.4】Pssdiag和Sqldiag管理器
--没有实操过,有点复杂,先写上以后有用到再深入研究 统计与诊断数据是任何 SQL故障修复工作的关键所在. 如果没有掌握这些数据,就无法确定数据性能问题的根源.数据表的瓶颈可能并不是由索引问题造成的: ...
- 04: DjangoRestFramework使用
Django其他篇 目录: 1.1 DjangoRestFramework基本使用 1.2 drf认证&权限 模块 1.3 djangorestframework 序列化 1.4 django ...
- Hbase0.96源码之HMaster(三)Hmaster主要循环
1.Master初始化 1.1 if (!this.stopped) { finishInitialization(startupStatus, false); loop(); } 1.2 finis ...
- sublime3跳转函数
点击Preferences->Browse Packages进入Packages目录,然后打开User目录,查看User目录里面有没有Default (Windows).sublime-mous ...
- CABasicAnimation animationWithKeyPath Types
转自:http://www.cnblogs.com/pengyingh/articles/2379631.html CABasicAnimation animationWithKeyPath 一些规定 ...
- 前端div+css
css基本结构: css的四种引入方式: 1.行内式:是在标记的style属性中设定CSS样式.这种方式没有体现出CSS的优势,不推荐使用. <p style="background- ...
- HBase(一)——HBase介绍
HBase介绍 1.关系型数据库与非关系型数据库 (1)关系型数据库 关系型数据库最典型的数据机构是表,由二维表及其之间的联系所组成的一个数据组织 优点: 1.易于维护:都是使用表结构,格 ...