題目鏈接:Codeforces - Pursuit For Artifacts
顯然,如果一個邊雙當中某個邊有1,那麼所有邊都可以看成1.
然後對於一棵樹直接dfs即可。
AC代碼:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=3e5+10,M=N<<1;
int n,m,low[N],dfn[N],dcc[N],val[N],vis[N],mark[M],d[N],cnt,co,st,ed;
int head[N],nex[M],to[M],w[M],tot=1;
vector<pair<int,int> > g[N]; stack<int> s;
inline void add(int a,int b,int c){
to[++tot]=b; nex[tot]=head[a]; w[tot]=c; head[a]=tot;
}
void Tarjan(int x){
dfn[x]=low[x]=++cnt; s.push(x),vis[x]=1;
for(int i=head[x];i;i=nex[i]){
if(mark[i]) continue; mark[i]=mark[i^1]=1;
if(!dfn[to[i]]) Tarjan(to[i]),low[x]=min(low[x],low[to[i]]);
else if(vis[to[i]]) low[x]=min(low[x],dfn[to[i]]);
}
if(low[x]==dfn[x]){
int u; co++;
do{
u=s.top(); s.pop(); vis[u]=0; dcc[u]=co;
}while(u!=x);
}
}
void dfs(int x,int fa){
for(auto to:g[x]) if(to.first!=fa){
d[to.first]=d[to.first]+d[x]+to.second; dfs(to.first,x);
}
}
signed main(){
cin>>n>>m;
for(int i=1,a,b,c;i<=m;i++) scanf("%d %d %d",&a,&b,&c),add(a,b,c),add(b,a,c);
cin>>st>>ed;
for(int i=1;i<=n;i++) if(!dfn[i]) Tarjan(i);
for(int i=1;i<=n;i++) for(int j=head[i];j;j=nex[j]){
if(dcc[i]==dcc[to[j]]) d[dcc[i]]+=w[j];
else g[dcc[i]].push_back({dcc[to[j]],w[j]});
}
dfs(dcc[st],dcc[st]);
puts(d[dcc[ed]]>0?"YES":"NO");
return 0;
}