https://www.luogu.org/problem/show?pid=2002
题目背景
本场比赛第一题,给个简单的吧,这 100 分先拿着。
题目描述
有n个城市,中间有单向道路连接,消息会沿着道路扩散,现在给出n个城市及其之间的道路,问至少需要在几个城市发布消息才能让这所有n个城市都得到消息。
输入输出格式
输入格式:
第一行两个整数n,m表示n个城市,m条单向道路。
以下m行,每行两个整数b,e表示有一条从b到e的道路,道路可以重复或存在自环。
输出格式:
一行一个整数,表示至少要在几个城市中发布消息。
输入输出样例
输入样例#1:
5 4 1 2 2 1 2 3 5 1
输出样例#1:
2
说明
【数据范围】
对于20%的数据,n≤200;
对于40%的数据,n≤2,000;
对于100%的数据,n≤100,000,m≤500,000.
【限制】
时间限制:1s,内存限制:256M
【注释】
样例中在4,5号城市中发布消息。
入度为0的强连通个数、
1 #include <cstdio> 2 3 #define min(a,b) (a<b?a:b) 4 inline void read(int &x) 5 { 6 x=0; register char ch=getchar(); 7 for(; ch>'9'||ch<'0'; ) ch=getchar(); 8 for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0'; 9 } 10 const int N(100005); 11 const int M(500005); 12 int head[N],sumedge; 13 struct Edge { 14 int v,next; 15 Edge(int v=0,int next=0):v(v),next(next){} 16 }edge[M]; 17 inline void ins(int u,int v) 18 { 19 edge[++sumedge]=Edge(v,head[u]); head[u]=sumedge; 20 } 21 22 int tim,dfn[N],low[N]; 23 int top,Stack[N],instack[N]; 24 int sumcol,col[N],ans,rd[N]; 25 void Tarjan(int u) 26 { 27 low[u]=dfn[u]=++tim; 28 Stack[++top]=u; 29 instack[u]=true; 30 for(int v,i=head[u]; i; i=edge[i].next) 31 { 32 v=edge[i].v; 33 if(!dfn[v]) Tarjan(v),low[u]=min(low[u],low[v]); 34 else if(instack[v]) low[u]=min(low[u],dfn[v]); 35 } 36 if(low[u]==dfn[u]) 37 { 38 col[u]=++sumcol; 39 for(; Stack[top]!=u; top--) 40 { 41 col[Stack[top]]=sumcol; 42 instack[Stack[top]]=false; 43 } 44 instack[u]=0; top--; 45 } 46 } 47 48 int Presist() 49 { 50 int n,m; read(n),read(m); 51 for(int u,v,i=1; i<=m; ++i) 52 read(u),read(v),ins(u,v); 53 for(int i=1; i<=n; ++i) 54 if(!dfn[i]) Tarjan(i); 55 for(int v,u=1; u<=n; ++u) 56 for(int i=head[u]; i; i=edge[i].next) 57 { 58 v=edge[i].v; 59 if(col[u]!=col[v]) rd[col[v]]++; 60 } 61 for(int i=1; i<=sumcol; ++i) if(!rd[i]) ans++; 62 printf("%d ",ans); 63 return 0; 64 } 65 66 int Aptal=Presist(); 67 int main(int argc,char*argv[]){;}