loj 1034(最小点基)

来源:互联网 发布:兔子白网络 编辑:程序博客网 时间:2024/06/15 07:05

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=25911

思路:强连通缩点,在新图中找入度为0的点的个数即可。

  1 #include<iostream>  2 #include<cstdio>  3 #include<cstring>  4 #include<iostream>  5 #include<cstdio>  6 #include<cstring>  7 #include<cstdlib>  8 #include<cmath>  9 #include<climits> 10 #include<algorithm> 11 #include<stack> 12 #include<map> 13 #include<set> 14 #include<vector> 15 #include<queue> 16 #include<list> 17 using namespace std; 18 #define MAXN 11111 19 #define inf 1<<30 20 #define INF 1LL<<60 21 #define FILL(a,b) memset(a,b,sizeof(a)) 22 typedef long long ll; 23 typedef unsigned long long llu; 24 typedef pair<int,int>PP; 25 template<class T> inline T Get_MIN(const T &a,const T &b){ return a < b ? a : b; } 26 template<class T> inline T Get_MAX(const T &a,const T &b){ return a > b ? a : b; } 27 template<class T> inline T ABS(const T &a){ return a < 0 ? -a : a; } 28  29 struct Edge{ 30     int v,next; 31 }edge[MAXN*20]; 32  33 int n,m,NE; 34 int head[MAXN]; 35  36 void Insert(int u,int v) 37 { 38     edge[NE].v=v; 39     edge[NE].next=head[u]; 40     head[u]=NE++; 41 } 42  43 int low[MAXN],dfn[MAXN],color[MAXN]; 44 bool mark[MAXN]; 45 int scc_count,cnt; 46 stack<int>S; 47 void Tarjan(int u) 48 { 49     low[u]=dfn[u]=++cnt; 50     mark[u]=true; 51     S.push(u); 52     for(int i=head[u];i!=-1;i=edge[i].next){ 53         int v=edge[i].v; 54         if(dfn[v]==0){ 55             Tarjan(v); 56             low[u]=Get_MIN(low[u],low[v]); 57         }else if(mark[v]){ 58             low[u]=Get_MIN(low[u],dfn[v]); 59         } 60     } 61     if(low[u]==dfn[u]){ 62         scc_count++; 63         int v; 64         do{ 65             v=S.top(); 66             S.pop(); 67             mark[v]=false; 68             color[v]=scc_count; 69         }while(u!=v); 70     } 71 } 72  73 int degree[MAXN]; 74  75 int main() 76 { 77     int _case,u,v,ans,t=1; 78     scanf("%d",&_case); 79     while(_case--){ 80         scanf("%d%d",&n,&m); 81         NE=0; 82         FILL(head,-1); 83         FILL(dfn,0); 84         FILL(mark,false); 85         cnt=scc_count=0; 86         while(m--){ 87             scanf("%d%d",&u,&v); 88             Insert(u,v); 89         } 90         for(int i=1;i<=n;i++)if(dfn[i]==0)Tarjan(i); 91         FILL(degree,0); 92         for(int u=1;u<=n;u++){ 93             for(int i=head[u];i!=-1;i=edge[i].next){ 94                 int v=edge[i].v; 95                 if(color[u]!=color[v]){ 96                     degree[color[v]]++; 97                 } 98             } 99         }100         ans=0;101         for(int i=1;i<=scc_count;i++)if(degree[i]==0)ans++;102         printf("Case %d: %d\n",t++,ans);103     }104     return 0;105 }
View Code

 

0 0
原创粉丝点击