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

    题目
    一看题目首先求个割点肯定是没问题的。
    然后考虑一下各个v-dcc。
    如果一个连通块没有割点,那么它就是孤立的,我们至少要放两个,这样在塌了一个的情况下和还能走另一个。当然如果只有一个点那么久只放一个。
    如果v-dcc有一个割点,那么我们可以把它理解为一个叶子节点。
    如果这个割点塌了那么这个叶子节点就出不去了,所以我们需要在这个v-dcc的非割点的节点中放一个,方案数为除了割点以外的这个v-dcc的大小。
    如果一个v-dcc有两个或以上的割点,那么说明它与两个或两个以上的v-dcc相邻,并且在塌了一个点的情况下一定能够到达一个有一个割点的放了的v-dcc,所以不需要放。

    #include<bits/stdc++.h>
    #define N 507
    using namespace std;
    namespace IO
    {
        char ibuf[(1<<21)+1],*iS,*iT;
        char Get() { return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++); }
        int read(){int x=0;char ch=Get();while(ch>57||ch<48)ch=Get();while(ch>=48&&ch<=57)x=x*10+(ch^48),ch=Get();return x;}
    }
    using namespace IO;
    vector<int>G[N];
    int low[N],dfn[N],Time,flg[N],root,sum,num,cut,cnt,vis[N];
    void tarjan(int u,int fa)
    {
        dfn[u]=low[u]=++Time;
        int i,v;
        for(i=0;i<G[u].size();++i)
    	if(!dfn[v=G[u][i]])
    	{
    	    tarjan(v,u),low[u]=min(low[u],low[v]);
    	    if(low[v]>=dfn[u]) if(u^root) flg[u]=1; else ++sum;
    	}
    	else if(v^fa) low[u]=min(low[u],dfn[v]);
    }
    void dfs(int u)
    {
        int i,v;
        vis[u]=cnt,++num;
        for(i=0;i<G[u].size();++i)
        {
    	if(flg[v=G[u][i]]&&vis[v]^cnt) ++cut,vis[v]=cnt;
    	if(!vis[v]) dfs(v);
        }
    }
    int main()
    {
        int i,n,m,u,v,T=0,ans;
        long long Ans;
        while(m=read())
        {
    	for(i=1;i<N;++i) G[i].clear();
    	memset(low,0,sizeof low),memset(dfn,0,sizeof dfn),memset(flg,0,sizeof flg),memset(vis,0,sizeof vis),Time=cnt=n=ans=0,Ans=1;
    	for(i=1;i<=m;++i) u=read(),v=read(),G[u].push_back(v),G[v].push_back(u),n=max(n,max(u,v));
    	for(i=1;i<=n;++i) if(!dfn[i]){root=i,sum=0,tarjan(i,i);if(sum>=2)flg[i]=1;}
    	for(i=1;i<=n;++i)
    	{
    	    if(!vis[i]&&!flg[i])
    	    {
    		++cnt,cut=num=0,dfs(i);
    		if(!cut) if(num==1) ++ans; else ans+=2,Ans*=1ll*(num-1)*num/2;
    		if(cut==1) ++ans,Ans*=num;
    	    }
    	}
    	printf("Case %d: %d %lld
    ",++T,ans,Ans);
        }
    }
    
  • 相关阅读:
    什么是shell
    Jenkins+python+selenium持续继承自动化测试
    selenium+python自动化
    产品和项目的概念
    继承与派生:赋值兼容规则(转)
    继承与派生:虚基类及其派生类的构造函数(转)
    重载函数与函数模板(转)
    继承与派生:作用域分辨符(转)
    作用域和可见性(转)
    继承与派生:派生类的析构函数(转)
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/11930203.html
Copyright © 2011-2022 走看看