• NOIP提高组DAY1T2——信息传递(最小环)


    描述
    有n个同学(编号为1到n)正在玩一个信息传递的游戏。在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学。
    游戏开始时,每人都只知道自己的生日。之后每一轮中,所有人会同时将自己当前所知的生日信息告诉各自的信息传递对象(注意:可能有人可以从若干人那里获取信息,但是每人只会把信息告诉一个人,即自己的信息传递对象)。当有人从别人口中得知自己的生日时,游戏结束。请问该游戏一共可以进行几轮?
    输入
    输入共2行。 第1行包含1个正整数 n,表示 n 个人。
    第2行包含 nn 个用空格隔开的正整数 T1,T2,⋯⋯,Tn,其中第 ii 个整数 Ti表示编号为 ii 的同学的信息传递对象是编号为 Ti的同学, Ti≤n 且 Ti≠i 。
    数据保证游戏一定会结束。
    输出
    输出共1行,包含1个整数,表示游戏一共可以进行多少轮。
    样例输入
    5
    2 4 2 3 1
    样例输出
    3

    题意很简单,就是求一个有向图的最小环

    既然都是一个环了,那我们就可以tarjan求强连通了,每次记录一下这个环的大小,最后把所有不为1的取个最小值就是了(为1的是单独一个点)

    强连通好容易写错啊

    #include<bits/stdc++.h>
    using namespace std;
    inline int read(){
        char ch=getchar();
        int res=0;
        while(!isdigit(ch))ch=getchar();
        while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
        return res;
    }
    const int N=200005;
    int adj[N],nxt[N<<1],to[N<<1],belnum,tot,vis[N],dfn[N],low[N],num[N],n,cnt;
    inline void addedge(int u,int v){
        nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v;
    }
    stack<int> stk;
    inline void tarjan(int u,int fa){
        dfn[u]=low[u]=++tot;
        stk.push(u);vis[u]=true;
        for(int e=adj[u];e;e=nxt[e]){
            int v=to[e];
            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(low[u]==dfn[u]){
            int tmp;belnum++;
            do{
                tmp=stk.top();
                stk.pop();
                vis[tmp]=0;
                num[belnum]++;
            }while(tmp!=u);
        }
    }
    int main(){
        n=read();
        for(int i=1;i<=n;i++){
            int u=read();
            addedge(i,u);
        }
        for(int i=1;i<=n;i++){
            if(!dfn[i]){
                tarjan(i,0);
            }
        }
        int ans=N;
        for(int i=1;i<=belnum;i++){
            if(num[i]!=1)
            ans=min(ans,num[i]);
        }
        cout<<ans;
    }
    
  • 相关阅读:
    【LCT维护基环内向树森林】BZOJ4764 弹飞大爷
    【LCT】BZOJ3091 城市旅行
    【LCT+主席树】BZOJ3514 Codechef MARCH14 GERALD07加强版
    【最大权闭合子图】bzoj4873 [Shoi2017]寿司餐厅
    【LCT】BZOJ2049 [SDOI2008]Cave 洞穴勘测
    【有上下界的网络流】ZOJ2341 Reactor Cooling(有上下界可行流)
    【费用流】BZOJ1061: [Noi2008]志愿者招募(这题超好)
    从输入url到页面加载的过程
    forEach和map的区别
    理解 JavaScript 对象原型、原型链如何工作、如何向 prototype 属性添加新的方法。
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366413.html
Copyright © 2020-2023  润新知