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

    Luogu_P3225 [HNOI2012]矿场搭建

    割点


    题目链接
    这种把点拿走明显就和割点有关系
    那么就先求割点
    求完割点然后???
    首先dfs每个割点分开的连通块
    如果这个连通块没有割点,必然要两个出口
    假如有这个联通有一个割点那么一定要放一个,因为假如割点塌了就需要这个点了
    假如有两个或者更多那么就不需要了,因为哪怕塌了割点也可以从别的割点走


    代码如下:

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=1010;
    int tim,n,m,head[maxn],tot,cnt,low[maxn],dfn[maxn],cut[maxn],rt,vis[maxn],cct,siz,cs;
    struct node{
        int nxt,to;
        #define nxt(x) e[x].nxt
        #define to(x) e[x].to
    }e[maxn<<1];
    inline void add(int from,int to){
        to(++tot)=to;nxt(tot)=head[from];head[from]=tot;
    }
    void tarjan(int x){
        dfn[x]=low[x]=++cnt;
        int fl=0;
        for(int i=head[x];i;i=nxt(i)){
            int y=to(i);
            if(!dfn[y]){
                tarjan(y);
                low[x]=min(low[x],low[y]);
                if(low[y]>=dfn[x]){
                    fl++;
                    if(x!=rt || fl>1) cut[x]=1;
                }
            }else low[x]=min(low[x],dfn[y]);
        }
    }
    void dfs(int x){
        vis[x]=tim;
        if(cut[x]) return;
        siz++;
        for(int i=head[x];i;i=nxt(i)){
            int y=to(i);
            if(cut[y] && vis[y]!=tim) cct++,vis[y]=tim;
            if(!vis[y]) dfs(y);
        }
    }
    int main()
    {
        while(scanf("%d",&m) && m){
            memset(head,0,sizeof(head));memset(e,0,sizeof(e));siz=tim=cnt=n=tot=cct=0;
            memset(low,0,sizeof(low));memset(dfn,0,sizeof(dfn));memset(cut,0,sizeof(cut));memset(vis,0,sizeof(vis));
            for(int x,y,i=1;i<=m;i++){
                scanf("%d%d",&x,&y);add(x,y);add(y,x);n=max(n,y);n=max(n,x);
            }
            for(int i=1;i<=n;i++) if(!dfn[i]) rt=i,tarjan(i);
            ll ans1=0,ans2=1;
            for(int i=1;i<=n;i++)
                if(!vis[i] && !cut[i]){
                    tim++;cct=siz=0;
                    dfs(i);
                    if(!cct)
                        ans1+=2,ans2*=siz*(siz-1)/2;
                    if(cct==1)
                        ans1++,ans2*=siz;
                }
            printf("Case %d: %lld %lld
    ",++cs,ans1,ans2);
        }
        return 0;
    }
    
  • 相关阅读:
    _ 下划线 Underscores __init__
    Page not found (404) 不被Django的exception中间件捕捉 中间件
    从装修儿童房时的门锁说起
    欧拉定理 费马小定理的推广
    线性运算 非线性运算
    Optimistic concurrency control 死锁 悲观锁 乐观锁 自旋锁
    Avoiding Full Table Scans
    批量的单向的ssh 认证
    批量的单向的ssh 认证
    Corrupted MAC on input at /usr/local/perl/lib/site_perl/5.22.1/x86_64-linux/Net/SSH/Perl/Packet.pm l
  • 原文地址:https://www.cnblogs.com/ChrisKKK/p/11652712.html
Copyright © 2011-2022 走看看