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

    Description

    煤矿工地可以看成是由隧道连接挖煤点组成的无向图。为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处。于是矿主决定在某些挖煤点设立救援出口,使得无论哪一个挖煤点坍塌之后,其他挖煤点的工人都有一条道路通向救援出口。请写一个程序,用来计算至少需要设置几个救援出口,以及不同最少救援出口的设置方案总数。

    Input

    输入文件有若干组数据,每组数据的第一行是一个正整数 N(N≤500),表示工地的隧道数,接下来的 N 行每行是用空格隔开的两个整数 S 和 T,表示挖       S 与挖煤点 T 由隧道直接连接。输入数据以 0 结尾。

    Output

    输入文件中有多少组数据,输出文件 output.txt 中就有多少行。每行对应一组输入数据的 结果。其中第 i 行以 Case i: 开始(注意大小写,Case 与 i 之间有空格,i 与:之间无空格,: 之后有空格),其后是用空格隔开的两个正整数,第一个正整数表示对于第 i 组输入数据至少需 要设置几个救援出口,第二个正整数表示对于第 i 组输入数据不同最少救援出口的设置方案总 数。输入数据保证答案小于 2^64。输出格式参照以下输入输出样例。

    Sample Input

    9
    1 3
    4 1
    3 5
    1 2
    2 6
    1 5
    6 3
    1 6
    3 2
    6
    1 2
    1 3
    2 4
    2 5
    3 6
    3 7
    0

    Sample Output

    Case 1: 2 4
    Case 2: 4 1

    HINT

    Case 1 的四组解分别是(2,4),(3,4),(4,5),(4,6);

    Case 2 的一组解为(4,5,6,7)。
     
    水题过来扔个模板
    塌掉一个点还能到,就找一下它的割点,分成联通块以后
    用乘法原理一搞就行了,woc会爆intWA了好几次
    //MT_LI
    #include<vector>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    struct node{
        int x,y,next;
    }a[410000];int len,last[41000];
    void ins(int x,int y)
    {
        len++;
        a[len].x=x;a[len].y=y;
        a[len].next=last[x];last[x]=len;
    }
    int m;
    int dfn[410000],low[410000];
    int cut[410000];
    int id,cnt,top,sta[410000];
    vector<int>block[41000];
    void tarjan(int x)
    {
        dfn[x]=low[x]=++id;
        sta[++top]=x;int flag=0;
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(dfn[y]==-1)
            {
                tarjan(y);
                low[x]=min(low[x],low[y]);
                if(low[y]>=dfn[x])
                {
                    cnt++;flag++;
                    if(x!=1||flag>1)cut[x]=1;
                    int i;
                    do{
                        i=sta[top--];
                        block[cnt].push_back(i);
                    }while(i!=y);
                    block[cnt].push_back(x);
                }
            }
            else low[x]=min(low[x],low[y]);
        }
    }
    int main()
    {
        int Case=0;
        while(scanf("%d",&m)!=EOF&&m)
        {
            int n;n=0;
            len=0;memset(last,0,sizeof(last));
            for(int i=1;i<=m;i++)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                n=max(max(x,n),y);
                ins(x,y);ins(y,x);
            }
            for(int i=1;i<=n;i++)block[i].clear();
            id=cnt=top=0;
            memset(cut,0,sizeof(cut));
            memset(dfn,-1,sizeof(dfn));
            tarjan(1);
            ll t=0;ll ans=1;
            for(int i=1;i<=cnt;i++)
            {
                int s=0;
                for(int j=0;j<block[i].size();j++)if(cut[block[i][j]])s++;if(s==1)t++,ans*=(ll)(block[i].size()-1);
            }
            
            if(!t)t=2,ans=n*(n-1)/2;
            printf("Case %d: %lld %lld
    ",++Case,t,ans);
        }
        return 0;
    }
  • 相关阅读:
    杯具,丢失了一部分邮件
    Android Building System 总结
    build/envsetup.sh
    PhoneApp是什么时候被创建的
    测试电信的WAP PUSH的方法
    修改Activity响应音量控制键修改的音频流
    ril崩溃时的出错地址定位
    java interface 强制类型转换小记
    android 修改系统程序图标大小
    git 合并patch的方法
  • 原文地址:https://www.cnblogs.com/MT-LI/p/9718787.html
Copyright © 2011-2022 走看看