题意: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】道路和航线(并查集,拓扑排序,最短路)的更多相关文章

  1. 并查集+拓扑排序 赛码 1009 Exploration

    题目传送门 /* 题意:无向图和有向图的混合图判环: 官方题解:首先对于所有的无向边,我们使用并查集将两边的点并起来,若一条边未合并之前, 两端的点已经处于同一个集合了,那么说明必定存在可行的环(因为 ...

  2. HDU 1811:Rank of Tetris(并查集+拓扑排序)

    http://acm.hdu.edu.cn/showproblem.php?pid=1811 Rank of Tetris Problem Description   自从Lele开发了Rating系 ...

  3. hdu 1811Rank of Tetris (并查集 + 拓扑排序)

    /* 题意:这些信息可能有三种情况,分别是"A > B","A = B","A < B",分别表示A的Rating高于B,等于B ...

  4. 【并查集+拓扑排序】【HDU1811】【Rank of Tetris】

    题意:给你3种关系 A=B,A>B,A<B 问是否排名方式唯一,或者存在矛盾 解 1.读入数据先处理 =号 用并查集的祖先作为代表元素,其他儿子节点都等于跟这个点重叠. 再读入 '< ...

  5. Codeforces Round #541 (Div. 2) D(并查集+拓扑排序) F (并查集)

    D. Gourmet choice 链接:http://codeforces.com/contest/1131/problem/D 思路: =  的情况我们用并查集把他们扔到一个集合,然后根据 > ...

  6. Codeforces Round #541 (Div. 2) D 并查集 + 拓扑排序

    https://codeforces.com/contest/1131/problem/D 题意 给你一个n*m二维偏序表,代表x[i]和y[j]的大小关系,根据表构造大小分别为n,m的x[],y[] ...

  7. HDU 1811 Rank of Tetris(并查集+拓扑排序 非常经典)

    Rank of Tetris Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  8. HDU 1811(并查集+拓扑排序)题解

    Problem Description 自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球.为了更好的符合那些爱好者的喜好,Lele又想了一个新点子:他 ...

  9. HDU 5222 ——Exploration——————【并查集+拓扑排序判有向环】

    Exploration Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

  10. HDU——1272小希的迷宫(并查集+拓扑排序)

    小希的迷宫 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Subm ...

随机推荐

  1. vue-devtools安装以后,勾选了“允许访问文件网址”之后还是无法使用

    勾选了“允许访问文件网址”,还是无法使用: Vue.js is detected on this page. Devtools inspection is not available because ...

  2. 多线程14-Barrier

    , b => Console.WriteLine());         ; i <= ; i++)             {                 Console.Write ...

  3. Oracle 修改数据文件路径的方法

      1. 关闭数据库,然后启动至mount状态 sqlplus / as sysdba shutdown immediate startup mount 2. 修改物理文件: 我这边将: c:\cwd ...

  4. 【监控笔记】【1.4】Pssdiag和Sqldiag管理器

    --没有实操过,有点复杂,先写上以后有用到再深入研究 统计与诊断数据是任何 SQL故障修复工作的关键所在. 如果没有掌握这些数据,就无法确定数据性能问题的根源.数据表的瓶颈可能并不是由索引问题造成的: ...

  5. 04: DjangoRestFramework使用

    Django其他篇 目录: 1.1 DjangoRestFramework基本使用 1.2 drf认证&权限 模块 1.3 djangorestframework 序列化 1.4 django ...

  6. Hbase0.96源码之HMaster(三)Hmaster主要循环

    1.Master初始化 1.1 if (!this.stopped) { finishInitialization(startupStatus, false); loop(); } 1.2 finis ...

  7. sublime3跳转函数

    点击Preferences->Browse Packages进入Packages目录,然后打开User目录,查看User目录里面有没有Default (Windows).sublime-mous ...

  8. CABasicAnimation animationWithKeyPath Types

    转自:http://www.cnblogs.com/pengyingh/articles/2379631.html CABasicAnimation animationWithKeyPath 一些规定 ...

  9. 前端div+css

    css基本结构: css的四种引入方式: 1.行内式:是在标记的style属性中设定CSS样式.这种方式没有体现出CSS的优势,不推荐使用. <p style="background- ...

  10. HBase(一)——HBase介绍

    HBase介绍 1.关系型数据库与非关系型数据库 (1)关系型数据库 ​ 关系型数据库最典型的数据机构是表,由二维表及其之间的联系所组成的一个数据组织 ​ 优点: ​ 1.易于维护:都是使用表结构,格 ...