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


    题目链接: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
    ",t++,ans);
    102     }
    103     return 0;
    104 }
    105 
    106 
    107 
    108         
    View Code
  • 相关阅读:
    一些常用的Unix命令
    Shortcut Blocks with Symbol to_proc 通过to_proc为代码块逻辑命名
    Using with_scope 使用with_scope
    Move Find into Model 将查询方法从控制器上移至模型
    Find Through Association 使用级联查询
    Dynamic find_by Methods 使用动态的find_by方法
    Caching with Instance Variables 缓存与实例变量
    深入浅出object-c
    IT大神进化史-第二章
    IT大神进化史-第一章
  • 原文地址:https://www.cnblogs.com/wally/p/3320800.html
Copyright © 2020-2023  润新知