洛谷—— P2002 消息扩散

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\n",ans);
63     return 0;
64 }
65 
66 int Aptal=Presist();
67 int main(int argc,char*argv[]){;}

 

posted @ 2017-09-29 08:14  Aptal丶  阅读(187)  评论(0编辑  收藏  举报