NOIP水题(1)——信息传递

好久没写博客了,因为上课了。每天就一节课来。理综(作业)要爆炸。。。数学已经爆炸。
但还是来一道水题吧。
P1979信息传递
这是个求最小环的题。(我们老师说的,我不懂,但我也只会这道题做法)

可以通过所给数据构成一个有向图(然并卵),重点是通过每个节点所指向的下个节点入度加一。
然后将没有入度的点删去(若成环,必有入度),再将它所指的节点入度减一。并判断是否有入度,若有则退出循环,没有则重复该操作。直到所有点遍历过后。
再将入度为1点深搜。比较得出最小环。

#include<stdio.h>
#include<string.h>
#include<stdbool.h>

int N,sum=0,h;
bool visit[200005];
int a[200005];
int in[200005];

int DFS(int num)
{
    int temp=num;
    visit[num]=true;
    in[a[temp]]--;//a[temp]表示下一个点 
    while(in[a[temp]]==0)
    {
        visit[a[temp]]=true;//下个点已被搜索 
        temp=a[temp];//temp为原来点指向点 
        in[a[temp]]--;
    }
    return 0;
}

int dfs(int num)
{
    int temp=num;
    sum=0;
    while(!visit[temp])
    {
        visit[temp]=true;
        sum++;
        temp=a[temp];
    }
//  printf("%d ",sum);
    return sum;

}

int main()
{
    int i,min=300000;

    memset(in,0,sizeof(in));
    memset(visit,0,sizeof(visit));


//  freopen("testdata.in","r",stdin);
//  freopen("testdata1.txt","w",stdout);

    scanf("%d",&N);

    for(i=1;i<=N;i++)
    {
        scanf("%d",&a[i]);
        in[a[i]]++;
    }

    for(i=1;i<=N;i++)//对每个入度为0的点深搜 
    {
        if(in[i]==0&&!visit[i])//visit表示若之前已被深搜过为0了,就不用再搜索了 
        DFS(i);
    }

/*  for(i=1;i<=N;i++)
    printf("%d ",in[i]);*/

    for(i=1;i<=N;i++)//得出最小环
    {
        if(!visit[i])
        {
            sum=dfs(i);
            if(sum<min)
            min=sum;
        }
    }

    printf("%d",min);
    return 0;
}

就在写博客时,突然发现了好多漏洞。。。又花了20多分钟。
就这样吧。

猜你喜欢

转载自blog.csdn.net/lumingjia819/article/details/52600924