洛谷—— P2002 消息擴散
阿新 • • 發佈:2017-09-29
中間 消息 個數 連通 輸入輸出 現在 www 限制 cnblogs
輸出樣例#1:
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
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 voidins(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\n",ans); 63 return 0; 64 } 65 66 int Aptal=Presist(); 67 int main(int argc,char*argv[]){;}
洛谷—— P2002 消息擴散