zoukankan      html  css  js  c++  java
  • [HNOI2012]矿场搭建

    题解:

    首先显然这是要缩点的 缩点双

    直接对割点之间的联通块判断一下连着几个割点

    连0个 cnt*(cnt-1)/2

    连1个 cnt

    连2个 0

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define N 2000
    bool iscut[N],ff[N];
    ll head[N],dfn[N],low[N],cc,now,l,num,cnt,T,color[N];
    ll n,m;
    struct re{
      ll a,b,c;
    }a[N];
    void arr(ll x,ll y)
    {
      a[++l].a=head[x];
      a[l].b=y;
      head[x]=l;
    }
    void tarjan(ll x,ll fa)
    {
      dfn[x]=low[x]=++now;
      ll child=0;
      ll u=head[x];
      while (u)
      {
        ll v=a[u].b;
        if (!dfn[v])
        {
          child++;
          tarjan(v,x);
          low[x]=min(low[x],low[v]);
          if (low[v]>=dfn[x]) iscut[x]=1;
        } else
        {
          if (v!=fa) low[x]=min(low[x],dfn[v]);
        }
        u=a[u].a;
      }
      if (fa==0&&child==1) iscut[x]=0;
    }
    void dfs(ll x)
    {
      color[x]=cc;
      if (iscut[x]) return;
      ff[x]=1; cnt++;
      ll u=head[x];
      while (u)
      {
        ll v=a[u].b;
        if (iscut[v]&&color[v]!=cc) num++;
        if (!ff[v]) dfs(v);
        u=a[u].a;
      }
    }
    int main()
    {
      freopen("noi.in","r",stdin);
      freopen("noi.out","w",stdout);
      while (cin>>m&&m)
      {
        T++;
        n=0; memset(head,0,sizeof(head));
        now=l=0;
        memset(iscut,0,sizeof(iscut));
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(ff,0,sizeof(ff));
        for (ll i=1;i<=m;i++)
        {
          ll x,y;
          cin>>x>>y;
          n=max(n,max(x,y));
          arr(x,y); arr(y,x);
        }
        for (ll i=1;i<=n;i++)
          if(!dfn[i]) tarjan(i,0);
        ll ans=1,ans1=0;
        for (ll i=1;i<=n;i++)
          if (!iscut[i]&&!ff[i])
          {
            num=0; cnt=0; cc++;
            dfs(i);
            if (num==0) ans*=max(1ll,cnt*(cnt-1)/2),ans1+=min(cnt,2ll);
            if (num==1) ans*=cnt,ans1++;
          }
        cout<<"Case "<<T<<": "<<ans1<<" "<<ans<<endl;
      }
      return 0;
    } 
  • 相关阅读:
    产品经理职责
    Python基础知识之:字符串拼接
    Python基础知识之:hello world,注释,变量,数据类型
    Python初接触
    系统测试基础大纲
    编程零基础应当如何开始学习 Python?
    可以用 Python 编程语言做哪些神奇好玩的事情?
    江湖二三事:听说你想做数据分析师?
    “羊车门”问题
    用Turtle画正螺旋线
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/8831728.html
Copyright © 2011-2022 走看看