• 刷题总结——date(ssoj)


    题目:

    题目背景

    SOURCE:NOIP2015-SHY-9

    题目描述

    小Y和小Z好不容易有机会相见啦,可是邪恶的小H却不想让他们相见。现在有一些城市,城市之间有双向路径相连,有路径相连的城市之间可以互相到达。小H可以任意选择一条路径,然后用他的邪恶力量污染这条路径,使得它不能被通行。虽然小Y和小Z在千辛万苦之后相遇了,但小Y非常害怕。她想让小Z告诉她,他们初始在哪些点对上,小H就可以选择一条路径污染使得他们不能相见。

    注意:如果有一对点之间初始的时候就不联通,也是满足条件的,需要输出这对点。这是因为本来不联通,那么删一条边,当然也不联通。

    输入格式

    第一行两个数字 N 和 M 。N 表示城市数,M 表示路径数。
    第二行到第 M+1 行,两个数 a 和 b。其中 1≤a,b≤N ,表示 a 和 b 之间有路径相连。

    输出格式

    输出一个整数,表示所求点对的数量

    样例数据 1

    输入  [复制]

    2 1 
    1 2

    输出

    1

    备注

    【样例说明】
    点对(1,2)满足不能相见的条件。

    【数据范围】
    对 30% 的输入数据 :1≤N≤100,1≤M≤200
    对 100% 的输入数据 :1≤N≤20000,1≤M≤40000

    题解: 

      就是求每个边双连通分量···然后双连通分量内的点肯定是可以相互到达的,因此我们先算出所有的点对··再减去所有双连通分量中的点对数量(都是合法点对)即可···

      另外注意处理重边以及断点的情况······md图论每次都被这两东西坑···

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<ctime>
    #include<cctype>
    #include<cstring>
    #include<string>
    #include<algorithm>
    using namespace std;
    const int N=2e4+5;
    const int M=4e4+5;
    int first[N],next[M*2],go[M*2],tot=1;
    int n,m,dfn[N],low[N],cnt=0;
    int totgroup,size[N];
    bool tag[M*2],visit[N];
    long long ans=0;
    inline int R()
    {
      char c;int f=0;
      for(c=getchar();c<'0'||c>'9';c=getchar());
      for(;c<='9'&&c>='0';c=getchar())
        f=(f<<3)+(f<<1)+c-'0';
      return f;
    }
    inline void comb(int a,int b)
    {
      next[++tot]=first[a],first[a]=tot,go[tot]=b;  
      next[++tot]=first[b],first[b]=tot,go[tot]=a;
    }
    inline void tarjan(int u,int pre)
    {
      dfn[u]=low[u]=++cnt;
      for(int e=first[u];e;e=next[e])
      {
        int v=go[e];
        if(!dfn[v])
        {
          tarjan(v,e);low[u]=min(low[u],low[v]);
          if(dfn[u]<low[v])  tag[e]=tag[e^1]=true;
        }
        else 
          if((e^1)!=pre)  low[u]=min(low[u],dfn[v]);
      }
    }
    inline void dfs(int u,int pre)
    {
      size[totgroup]++;visit[u]=true;
      for(int e=first[u];e;e=next[e])
      {
        if(!tag[e]&&(e^1)!=pre&&!visit[go[e]])
        { 
          int v=go[e];dfs(v,e);    
        }
      }
    }
    int main()
    {
      //freopen("a.in","r",stdin);
      n=R(),m=R();int a,b;
      for(int i=1;i<=m;i++)
      {
        a=R(),b=R();
        comb(a,b);
      }
      for(int i=1;i<=n;i++)
         if(!dfn[i])  tarjan(i,-1);
      for(int i=1;i<=n;i++)
      {  
        if(!visit[i])  totgroup++,dfs(i,-1);
      }
      ans=(long long)n*(n-1)/2;
      for(int i=1;i<=totgroup;i++)
        ans-=(long long)size[i]*(size[i]-1)/2;
      cout<<ans<<endl;
      return 0;
    }
  • 相关阅读:
    去掉苹果设备中按钮的默认样式
    用纯css写三角形
    行内元素中间出现空隙
    控制字间距
    单选按钮只能选中一个
    ie6出现双倍边距的问题
    17-比赛1 B
    ACM模板
    STL 入门 (17 暑假集训第一周)
    UVA 1594 Ducci Sequence(紫书习题5-2 简单模拟题)
  • 原文地址:https://www.cnblogs.com/AseanA/p/7638465.html
Copyright © 2020-2023  润新知