UVALive 6044(双连通分量的应用)

来源:互联网 发布:於于同:无主之花 知乎 编辑:程序博客网 时间:2024/05/17 03:40

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

思路:首先是双连通缩点,然后就是搜索一下,搜索时要跳过连通分量的点的个数>=2的点,最后的答案是n*(n-1)/2.

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

 

 

0 0
原创粉丝点击