首页 > 其他分享 >Pursuit For Artifacts 题解(图论)

Pursuit For Artifacts 题解(图论)

时间:2024-02-27 19:11:19浏览次数:28  
标签:连通 temp Artifacts 题解 sccnt int Pursuit fi low

Pursuit For Artifacts 题解

题目

  • 给定一张 \(n\) 个点 \(m\) 条边的简单无向连通图,边有边权,边权要么为 \(0\),要么为 \(1\)。
  • 每条边只能通过一次(两个方向加起来只能通过一次)。
  • 求是否存在一条从 \(a\) 到 \(b\) 的路径,满足路径上至少存在一条权为 \(1\) 的边。
  • \(1 \leq n, m \leq 3 \times 10^5\)。

思路

因为是无向图,我们发现如果一个图里有边双连通分量,并且如果这个连通分量里只要有一条边1,那么这群点就可以全看做为1的点。于是首先,我们使用tarjan处理这个图,将其缩为边双连通分量。然后我们得到了一棵树,数的结点表示该连通分量。此时如果a和b在同一块连通分量,那么看一下这个连通分量里有没有边权为1的边即可,否则遍历这棵树,查询两点间路径里有没有权为1的点或权为1的边即可。

代码实现

#include<bits/stdc++.h>
#define fi first
#define se second
#define lowbit(x) (x&(-x))
using namespace std;
typedef pair<int,int> pii;
void solve(){
    int n,m;cin>>n>>m;
    vector<vector<pii>>e(n+1);
    while(m--){
        int u,v,w;cin>>u>>v>>w;
        e[u].emplace_back(v,w);
        e[v].emplace_back(u,w);
    }
    vector<int>dfsn(n+1),low(n+1),instk(n+1),scc(n+1);
    stack<int>stk;
    int dfscnt=0,sccnt=0;
    function<void(int,int)>tarjan=[&](int u,int fa){
        dfsn[u]=low[u]=++dfscnt;
        instk[u]=1;
        stk.push(u);
        for(auto v:e[u]){
            if(v.fi==fa)continue;
            if(!dfsn[v.fi]){
                tarjan(v.fi,u);
                low[u]=min(low[u],low[v.fi]);
            }
            else if(instk[v.fi])low[u]=min(low[u],dfsn[v.fi]);
        }
        if(dfsn[u]==low[u]){
            int temp;
            do{
                temp=stk.top();
                stk.pop();
                instk[temp]=0;
                scc[temp]=sccnt;
            }while(temp!=u);
            sccnt++;
        }
    };
    for(int i=1;i<=n;i++)if(!dfsn[i])tarjan(i,0);
    vector<int>col(sccnt);
    vector<vector<pii>>newe(sccnt);
    for(int i=1;i<=n;i++)
        for(auto j:e[i]){
            if(scc[i]==scc[j.fi]){
                if(j.se)col[scc[i]]=1;
            }
            else{
                newe[scc[i]].emplace_back(scc[j.fi],j.se);
            }
        }
    int x,y;cin>>x>>y;
    x=scc[x];y=scc[y];
    if(x==y){
        if(col[x])cout<<"YES\n";
        else cout<<"NO\n";
        return ;
    }
    int flag=0;
    function<void(int,int,int)>dfs=[&](int u,int f,int fa){
        f|=col[u];
        if(u==y){
            if(f){cout<<"YES\n";flag=1;return ;}
        }
        for(auto j:newe[u])if(j.fi!=fa)dfs(j.fi,f|j.se,u);
    };
     dfs(x,0,-1);
     if(!flag)cout<<"NO\n";
}
signed main(){
    std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);
    srand((unsigned)time(NULL));
    //int t;std::cin>>t;while(t--)
    solve();
}

标签:连通,temp,Artifacts,题解,sccnt,int,Pursuit,fi,low
From: https://www.cnblogs.com/shi5/p/18035085

相关文章

  • CF1864C 题解
    \(x=2^k\)是好做的,每次以\(2^{k-1}\)为因数即可。对于其他情况,考虑每次让\(x\)减去其二进制下最低位的\(1\)直至变成\(2^k\)。这种策略下显然每个数只会在以上两个大步骤下取到,故每个数使用不超过\(2\)次。同时操作次数在\(O(\logn)\)这个量级。#include<bits/......
  • P7086 题解
    考虑把每个字符串的前\(k\)位和后\(k\)位看成点,字符串看成边,那么一个字符串前缀后缀至少有一个是相似群体的前缀后缀,看成这条边的两个端点至少有一个被选中。那么这就变成了一个最小点覆盖问题。考虑匈牙利算法算出答案,然后考虑如何构造答案。考虑右边没有被匹配的点,选中这......
  • AT_abc317_f 题解
    调了一小时结果发现爆longlong了。考虑数位dp,具体来说,设计状态\(dp_{i,r_1,r_2,r_3,mx_1,mx_2,mx3_,c_1,c_2,c_3}\)表示当前考虑到第\(i\)位,\(x_1,x_2,x_3\)模\(a_1,a_2,a_3\)等于\(r_1,r_2,r_3\)三个数是否达到\(n\)的上界以及是否全部是\(0\)。然后从高到低枚......
  • AT_joisc2019_j 题解
    先考虑这个式子:\[\sum_{j=1}^{M}|C_{k_{j}}-C_{k_{j+1}}|\]一定是在\(C\)有序时取到,具体证明很简单各位读者自己证明。那么现在式子变成:\[\sum{V}+2\times({C_{\max}-C_{\min}})\]这个时候一个常见的技巧是将\(C\)排序。这个时候就可以定义状态:\[dp_{i,j}=\s......
  • CF1862G 题解
    首先这个查询操作很迷,考虑先化简查询操作。不难发现由于每次是加上一个逆的等差序列,因此一次操作完每个数与它的前驱之差一定会减少,因此加上等差序列的次数就等于全局每个数与它的前驱之差最大值。又因为会排序去重,所以最后剩下来的数一定是最开始的数一路加过来的,至此我们发现......
  • P5837 [USACO19DEC] Milk Pumping G 题解
    原题传送门思路只用堆每一个点跑一边最短路,在用当前点到点\(n\)的距离,再用当前点的\(f\)乘上\(10^6\)除以刚刚算出的值即可。代码#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<queue>usingnamespacestd;#defin......
  • P2350 [HAOI2012] 外星人 题解
    很巧妙的一道题。首先会发现如果最终\(\varphi(N)=1\)的话一定是通过很多次从\(2\)这个因子变到\(1\)的。而这个函数每迭代一次,就会有且仅有一个\(2\)的因子变为\(1\)。所以题目转化为了求\(N\)在函数迭代过程中一共会产生多少个\(2\)的因子。考虑\(\text{dp}\),设......
  • U332154 carbon 题解(期望)
    这题其实挺简单的......首先我们手模样例,对于第一组样例其实就是在1-n之间取一个数,求取到的数的期望。所以E(x)=\(\frac{1+n}{2}\)。对于第二组样例,我们首先将所有可能情况枚举出来:1010101010101010101099999999910888888889......
  • U329011 trie pi 题解
    花了2d打磨出来的题目,觉得很有意思。先讲点无关的,这道题有两版,但都是对要求的量进行改动。1.第一次要求的是y属性为a与y属性为b的两个节点的路径权值之和,对于要求的这个量,我们设v[i]为i到根节点的权值之和。那么我们先对a,b进行质因数分解,设dcg为a,b分解质因数后最长公共前缀的乘......
  • 时间戳时区问题解决方法
    在大家开发时会遇到这种情况:服务器是以东八时区为准(即中国标准时间),但是客户端会在不同地方,比如说雅典开罗(+2),格陵兰(-3),夏威夷(-10),当客户端选择某一个时间后,传递给服务器的时间戳,是以当地时区来解析的时间戳,这样就会出现一个时间差的问题,从而造成时间不准确。下面我们就来解决这种问......