• 洛谷 P2661 信息传递 题解


    这道题根据题意可以理解为在图中找一个最小环的问题

    又因为题目中一条重要的性质:每个点出度都为1,所以我想到了一个删边的做法。

    详细来讲就是递归删去除环以外的边(即原本或更新后入度为1的边),剩下一个个独立无交集的环,再遍历一遍就能找出答案。

    注:每个点在删边和搜环时只会遍历一遍,所以程序并不会超时。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxn 200010
    #define int long long
    #define rep(i,s,e) for(register int i=s;i<=e;++i)
    #define dwn(i,s,e) for(register int i=s;i>=e;--i)
    using namespace std;
    inline int read()
    {
        int x=0,f=1;
        char c=getchar();
        while(c<'0'||c>'9') {if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9') {x=x*10+c-'0'; c=getchar();}
        return f*x;
    }
    inline void write(int x)
    {
        if(x<0){putchar('-');x=-x;}
        if(x>9)write(x/10);
        putchar(x%10+'0');
    }
    int n,ans=99999999;
    int a[maxn],r[maxn],book[maxn]; 
    void remove(int x)
    {
        --r[a[x]];
        book[x]=-1;
        if(r[a[x]]==0&&book[a[x]]==0) remove(a[x]);
    }
    void dfs(int x,int st,int step)
    {
    //    cout<<x<<" "<<st<<" "<<step<<endl;
    //    getchar();
        if(x==st&&step!=0)
        {
            ans=min(ans,step);
            return;
        }
        book[x]=1;
        dfs(a[x],st,step+1);
    }
    signed main()
    {
        n=read();
        rep(i,1,n) 
        {
            a[i]=read();
            ++r[a[i]];
        }
        rep(i,1,n)
        {
            if(r[i]==0&&book[i]!=-1) remove(i);
        } 
        rep(i,1,n)
        {
            if(book[i]==0) dfs(i,i,0);
        }
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    Javascript MVC学习杂记3
    Backbone.js 0.9.2 源码分析收藏
    Javascript MVC学习杂记2
    Javascript MVC学习杂记1
    C语言string.h中常用字符函数介绍
    10点网页设计要注意的细节
    js日期函数
    结合回调函数介绍下泛型函数
    【转载】互斥量和信号量的区别
    设计模式之Singleton
  • 原文地址:https://www.cnblogs.com/handsome-zyc/p/13616233.html
Copyright © 2020-2023  润新知