好久没写博客了,因为上课了。每天就一节课来。理综(作业)要爆炸。。。数学已经爆炸。
但还是来一道水题吧。
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多分钟。
就这样吧。