codeforces 652 E(无向图tarjan缩点)

版权声明:写了自己看的,看不懂不能怪我emmmm。 https://blog.csdn.net/qq_40858062/article/details/87891122

链接:https://codeforces.com/group/w1oiqifZbS/contest/652/problem/E

思路:在同一个强连通分量中,假如有两个节点u和v,和一条有效边s,我一定能从u,通过一条路径走到v,并且经过s

这就是缩点后还能搞的原理了。缩点后只要看从s到t的路径是否有点权或者边权不为0的就好了

#pragma GCC optimize(2)
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <bitset>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <sstream>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll inff = 0x3f3f3f3f3f3f3f3f;
#define FOR(i,a,b) for(int i(a);i<=(b);++i)
#define FOL(i,a,b) for(int i(a);i>=(b);--i)
#define REW(a,b) memset(a,b,sizeof(a))
#define inf int(0x3f3f3f3f)
#define si(a) scanf("%d",&a)
#define sl(a) scanf("%lld",&a)
#define sd(a) scanf("%lf",&a)
#define ss(a) scanf("%s",a)
#define mod ll(1000)
#define pb push_back
#define eps 1e-8
#define lc d<<1
#define rc d<<1|1
#define Pll pair<ll,ll>
#define P pair<int,int>
#define pi acos(-1)
int deep,dfn[300008],low[300008],vis[300008],z[300008],e[300008],sum,tmp,n,m,s,t,d[300008],ss;
vector<P> g[300008],ne[300008];
stack<int> st;
void tarjan(int u,int fa)
{
    dfn[u]=low[u]=++deep;
    vis[u]=1,st.push(u);
    for(int i=0;i<g[u].size();i++)
    {
        int v=g[u][i].first;
        if(v==fa) continue;
        if(!dfn[v])
        {
            tarjan(v,u);
            low[u]=min(low[u],low[v]);
        }
        else if(vis[v])  low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u])
    {
        sum++,tmp=0;
        while(tmp!=u)
        {
            tmp=st.top();st.pop();
            z[tmp]=sum;
            vis[tmp]=0;
        }
    }
}
bool dfs(int u,int fa,int t,int ss)
{
    ss+=d[u];
    if(u==t&&ss) return 1;
    for(int i=0;i<ne[u].size();i++)
    {
        int v=ne[u][i].first;
        if(v==fa) continue;
        if(dfs(v,u,t,ss+ne[u][i].second)) return 1;
    }
    return 0;
}
int main()
{
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m;
    int x,y,zz;
    while(m--)
    {
        si(x),si(y),si(zz);
        g[x].pb(P(y,zz));
        g[y].pb(P(x,zz));
    }
    cin>>s>>t;
    FOR(i,1,n)  if(!dfn[i])  tarjan(i,0);
    FOR(i,1,n)
    {
        for(int j=0;j<g[i].size();j++)
        {
            if(z[i]!=z[g[i][j].first])  ne[z[i]].pb(P(z[g[i][j].first],g[i][j].second));
            else d[z[i]]+=g[i][j].second;
        }
    }
    if(dfs(z[s],0,z[t],0)) puts("YES");
    else  puts("NO");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40858062/article/details/87891122
今日推荐