• 刷题总结——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;
    }
  • 相关阅读:
    hiho_1081_最短路径1
    hiho_1079_离散化
    hiho_1078_线段树区间修改
    hiho_1069_最近公共祖先3
    【.netcore学习】.netcore添加到 supervisor 守护进程自启动报错
    【.NetCore学习】ubuntu16.04 搭建.net core mvc api 运行环境
    【.NetCore学习】ASP.NET Core EF Core2.0 DB First现有数据库自动生成实体Context
    【vue基础学习】vue.js开发环境搭建
    【vue学习】vue中怎么引用laydate.js日期插件
    【年终总结】个人的2017年年终总结
  • 原文地址:https://www.cnblogs.com/AseanA/p/7638465.html
Copyright © 2020-2023  润新知