zoukankan      html  css  js  c++  java
  • loj10099 矿场搭建

    传送门

    分析

    我们发现可以将这张图转换为一个联通块来处理。我们求出所有的割点。在求完之后我们我们对于每一个点双连通分量如果它没有割点相连则需要布置两个出口,因为可能有一个出口正好被割掉。而如果有一个割点我们只需要布置一个出口就行了,因为如果割掉割点可以从出口出去而如果割掉出口便可以通过割点到别的联通块中从而出去。而如果大于等于两个割点则无论如何都可以出去。至于方案数用组合数随便做一下就行了。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    long long dfn[520],low[520],is[520],cnt,n,m,ans,minn,vis[520],T,tot,siz;
    map<long long,long long>id;
    vector<long long>v[520];
    inline void init(){
          for(int i=0;i<=500;i++)v[i].clear();
          id.clear();
          memset(dfn,0,sizeof(dfn));
          memset(low,0,sizeof(low));
          memset(is,0,sizeof(is));
          memset(vis,0,sizeof(vis));
          ans=1;
          minn=0;
          cnt=0;
          n=0;
          T=0;
    }
    inline void tarjan(long long x,long long fa){
          dfn[x]=low[x]=++cnt;
          long long son=0;
          for(long long i=0;i<v[x].size();i++)
            if(v[x][i]!=fa){
              if(!dfn[v[x][i]]){
                son++;
                tarjan(v[x][i],x);
                low[x]=min(low[x],low[v[x][i]]);
                if(low[v[x][i]]>=dfn[x])is[x]=1;
              }else low[x]=min(low[x],dfn[v[x][i]]);
            }
          if(!fa&&son==1)is[x]=0;
          return;
    }
    inline void work(long long x){
          siz++;
          vis[x]=T;
          for(long long i=0;i<v[x].size();i++)
            if(!vis[v[x][i]]&&!is[v[x][i]])work(v[x][i]);
              else if(is[v[x][i]]&&vis[v[x][i]]!=T)tot++,vis[v[x][i]]=T;
    } 
    int main(){
          long long i,j,k,t=0;
          scanf("%lld",&m);
          while(m){
              t++;
              init();
              for(i=1;i<=m;i++){
                long long x,y;
                scanf("%lld%lld",&x,&y);
                if(!id[x])id[x]=++n;
                if(!id[y])id[y]=++n;
                v[id[x]].push_back(id[y]);
                v[id[y]].push_back(id[x]);
              }
              for(i=1;i<=n;i++)
                if(!dfn[i])tarjan(i,0);
              for(i=1;i<=n;i++)
                if(!vis[i]&&!is[i]){
                    T++;
                    tot=0,siz=0;
                work(i);
                if(tot==0)minn+=2,ans*=(siz-1)*siz/2;
                  else if(tot==1)minn+=1,ans*=siz;
                }
              printf("Case %lld: ",t);
              printf("%lld %lld
    ",minn,ans);
              scanf("%lld",&m);
          }
          return 0;
    }
  • 相关阅读:
    c语言printf实现同一位置打印输出
    https加解密过程
    矩形重叠判断
    cocos creator Touch事件应用(触控选择多个子节点)
    js动态创建类对象
    HTTP ERROR 400 Bad Request
    JavaScript(JS)计算某年某月的天数(月末)
    spring hibernate实现动态替换表名(分表)
    Zookeeper实现分布式锁
    Spring FactoryBean和BeanFactory 区别
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9525096.html
Copyright © 2011-2022 走看看