【题解】AtCoder-ABC306_G Return to 1

Page Views Count

这也太强了!

容易想到的是用若干环拼出这个 1010100,也就是这些环的 gcd1010100

之后就不会了。

先正图反图两次 DFS,只留下 1 所在强连通分量里的边,对正图跑 DFS 生成树,定义其深度从 0 开始,然后有一个结论是:对于任何正整数 a,图中存在一个包含 1 的且长度不是 a 的倍数的环的充要条件是存在一条图上的边 (u,v) 使 depu+1depv0(moda)

下面是证明。

必要性考虑证明逆否命题,即若不存在一条图上的边 (u,v) 使 depu+1depv0(moda),则图中包含 1 的环的长度都是 a 的倍数。这是显然的,由于这样的环深度从 0 开始,每次移动都相当于深度在模 a 意义下加 1,又回到 0,所以环长一定是 a 的倍数。

充分性不知道题解在说什么,但是若存在这样 depu+1depv0(moda) 的边,就说明 (u,v) 是非树边且 uv 是由两条不同的根链遍历到的,由于 depu+1depv0(moda),那么 1u 的根链长加 11v 的根链长,在模 a 意义下不同余,也就是两条 1v 的路径长不同余。这时候同样是从 v 回到 1,两个环长度一定不同余,那么至少有一个不是 a 的倍数。

这样我们对所有环求 gcd 就可以对所有 depu+1depvgcd

点击查看代码
int t;
int n,m;
vector<int> E1[maxn],E2[maxn];
bool vis1[maxn],vis2[maxn];
int dep[maxn];
void dfs1(int u,int d){
    vis1[u]=true,dep[u]=d;
    for(int v:E1[u]){
        if(vis1[v]) continue;
        dfs1(v,d+1);
    }
}
void dfs2(int u){
    vis2[u]=true;
    for(int v:E2[u]){
        if(vis2[v]) continue;
        dfs2(v);
    }
}
int main(){
    t=read();
    while(t--){
        n=read(),m=read();
        for(int i=1;i<=n;++i){
            E1[i].clear(),E2[i].clear();
            vis1[i]=false,vis2[i]=false,dep[i]=0;
        }
        for(int i=1;i<=m;++i){
            int u=read(),v=read();
            E1[u].push_back(v);
            E2[v].push_back(u);
        }
        dfs1(1,0);
        dfs2(1);
        int g=0;
        for(int u=1;u<=n;++u){
            if(!vis1[u]||!vis2[u]) continue;
            for(int v:E1[u]){
                if(!vis1[v]||!vis2[v]) continue;
                if(!g) g=abs(dep[u]+1-dep[v]);
                else g=__gcd(g,abs(dep[u]+1-dep[v]));
            }
        }
        if(!g) printf("No\n");
        else{
            while(g%2==0) g/=2;
            while(g%5==0) g/=5;
            if(g==1) printf("Yes\n");
            else printf("No\n");
        }
    }
    return 0;
}

作者:SoyTony

出处:https://www.cnblogs.com/SoyTony/p/Solution_on_AtCoder-ABC306_G.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   SoyTony  阅读(49)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
more_horiz
keyboard_arrow_up light_mode palette
选择主题
点击右上角即可分享
微信分享提示