Educational Codeforces Round 10
E
题意
给一张无向图,某些路径上有货物。给定起止点,询问是否存在一条从起点到中点的简单路径,路上有至少一个货物。
题解
对于一个强连通分量,如果分量中有货物,那么对于任意两点,必然存在一条路径经过货物。因此我们可以将强连通分量缩成一个点,如果强连通分量中有货物,则这个强连通分量缩成的点的点权就是1,否则是0。
缩点之后,整个图变成一个树,起点的强连通分量到终点的强连通分量之间有唯一路径,接下来要做的就是判断起点到终点的路径之间的点或边上是否有货物,搜索一下就可以了。
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 3e5 + 10;
const int M = 3e5 + 10;
struct EDGE{
int to, v, nxt;
EDGE(){}
EDGE(int x, int y, int z)
{ to = x; nxt = y; v = z;}
}edge[M * 2], newedge[M * 2];
int t[N], newt[N], val[N], pre[N];
int low[N], dfn[N], st[N], in[N], col[N], fa[N];
int k, newk, colcnt, cnt, stop;
void addedge(int x, int y, int v)
{
edge[++k] = EDGE(y, t[x], v);
t[x] = k;
}
void addnewedge(int x, int y, int v)
{
newedge[++newk] = EDGE(y, newt[x], v);
newt[x] = newk;
}
void dfs(int x, int fr)
{
dfn[x] = ++cnt;
low[x] = cnt;
in[x] = 1;
st[++stop] = x;
for(int p = t[x]; p; p = edge[p].nxt)
{
int y = edge[p].to;
if(y == fr)
continue;
if(!dfn[y])
{
dfs(y, x);
low[x] = min(low[x], low[y]);
}
else
{
if(in[y])
low[x] = min(low[x], dfn[y]);
}
}
if(dfn[x] == low[x])
{
colcnt++;
int y = st[stop];
do{
y = st[stop];
in[y] = 0;
col[y] = colcnt;
stop--;
}while(y != x);
}
}
void getnewmap(int n, int m)
{
for(int i = 1; i <= n; i++)
{
for(int p = t[i]; p; p = edge[p].nxt)
{
int y = edge[p].to;
if(col[i] != col[y])
{
addnewedge(col[i], col[y], edge[p].v);
}
else
{
val[col[i]] = max(val[col[i]], edge[p].v);
}
}
}
}
void dfs2(int x, int fr)
{
for(int p = newt[x]; p; p = newedge[p].nxt)
{
int y = newedge[p].to;
if(y == fr)
continue;
fa[y] = x;
pre[y] = newedge[p].v;
dfs2(y, x);
}
}
int judge(int x, int y)
{
dfs2(x, 0);
int ans = val[x];
while(y != x)
{
ans = max(ans, max(val[y], pre[y]));
y = fa[y];
}
return ans;
}
int main()
{
int n, m, x, y, z;
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i++)
{
scanf("%d%d%d", &x, &y, &z);
addedge(x, y, z);
addedge(y, x, z);
}
for(int i = 1; i <= n; i++)
if(!dfn[i])
dfs(i, 0);
getnewmap(n, m);
scanf("%d%d", &x, &y);
x = col[x];
y = col[y];
if(judge(x, y))
printf("YES\n");
else
printf("NO\n");
return 0;
}