原题:1269
题意:
有n个灯塔m条关系,每条关系a,b代表a她可以往b塔传消息,问你告诉几个塔就可以传遍所有塔。
解析:
首先把所有塔分为两种:有通向此塔的其他塔的塔——子塔,和必须由你来告诉的塔——母塔。
对于第二种,我们做一遍dfs,删去下面可以延伸的子塔,剩下的只有两种塔了:原先的母塔,和自成环路的子塔群。我们再对所有的塔删一遍,同时记录dfs的次数就是ans。
代码:
#include<stdio.h>
int canfin[100009];
int ishead[100009];
int head[100009];
struct edge{
int to,nex;
}e[1000009];
void fin(int ar){
int mid;
for(int i=head[ar];i>=0;i=e[i].nex){
mid=e[i].to;
if(!canfin[mid]){
canfin[mid]=1;
fin(mid);
}
}
return;
}
int main(){
int n,m,x,y,i;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
head[i]=-1;ishead[i]=1;
}
for(i=1;i<=m;i++){
scanf("%d%d",&x,&y);
e[i].to=y;e[i].nex=head[x];head[x]=i;
ishead[y]=0;//==1代表母塔
}
for(i=1;i<=n;i++){
if(!ishead[i])continue;
if(canfin[i])continue;//已经删过了
fin(i);
}
int sum=0;
for(i=1;i<=n;i++){
if(!canfin[i])
sum++,
fin(i);
}
printf("%d\n",sum);
return 0;
}
还有一个东西,cstdio换成stdio.h时间减少了80%