zoukankan      html  css  js  c++  java
  • 洛谷P3469 [POI2008]BLO-Blockade (Tarjan判割点+dfs树切割)

    题目链接:https://www.luogu.com.cn/problem/P3469

    题目解法:

    错解(50pts):我先用Tarjan跑了一把找到所有割点,因为非割点的话造成的影响肯定是2*(n-1),所以我们要特殊处理割点的情况。于是呢,我就把割点的相临点全部跑了一把bfs找该组有几个点,然后总点数带来的贡献-各个小组点数带来的贡献和就是最后答案。但是这个复杂度爆了TLE,所以只有50pts

    AC解法(100pts):利用tarjan的同时建立dfs树,因为low[v]>=dfn[x]就能判断x是不是割点。在dfs树上会有一些假子节点。而通过刚刚那个判断,我们可以把每一个真子结点进行处理,if(low[v]>=dfn[x]) siz[x]+=siz[v],这个情况就是真子节点因为low[v]和dfn[x]之间 >的情况是是一个单链,而=的情况是一个环。建成真的dfs树后,后面的处理就容易想了。

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define per(i,n,a) for(int i=n;i>=a;i--)
    #define endl '
    '
    #define eps 0.000000001
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define IO ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    const int INF=0x3f3f3f3f;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    const int mod=1e9+7;
    const int maxn=5e5+5;
    int tot,head[maxn];
    struct E{
        int to,next;
    }edge[maxn<<1];
    void add(int u,int v){
        edge[tot].to=v;
        edge[tot].next=head[u];
        head[u]=tot++;
    }
    int n,m;
    int id[maxn],dfn[maxn],low[maxn],tott,cnt;
    stack<int> s;int fa[maxn],cut[maxn];
    vector<int> bccs[maxn];int siz[maxn];ll ans[maxn];
    void tarjan(int x){
        low[x]=dfn[x]=++tott;
        s.push(x);int son=0;siz[x]=1;ll sum=0;
        for(int i=head[x];i!=-1;i=edge[i].next){
            int v=edge[i].to;
            if(!dfn[v]){
                ++son;fa[v]=x;
                tarjan(v);siz[x]+=siz[v];
                low[x]=min(low[x],low[v]);
                if(low[v]>=dfn[x]){
                    cut[x]=true;
                    ans[x]+=1LL*siz[v]*(n-1-siz[v]);        
                    sum+=siz[v];
                    ++cnt;
                    bccs[cnt].clear();
                    while(1){
                        int now=s.top();s.pop();
                        id[now]=cnt;
                        bccs[cnt].push_back(now);
                        if(now==v) break;
                    }
                    id[x]=cnt;
                    bccs[cnt].push_back(x);
                }
            }
            else if(v!=fa[x]) low[x]=min(low[x],dfn[v]);
        }
        if(fa[x]==-1&&son==1) cut[x]=false;
        if(!cut[x]) ans[x]=2*(n-1);
        else{
            ans[x]+=1LL*(n-sum-1)*(sum)+2*(n-1);
        }
    }
    int main(){
        cin>>n>>m;mem(head,-1);
        rep(i,1,m){
            int u,v;cin>>u>>v;
            add(u,v);add(v,u);
        }
        rep(i,1,n){
            if(!dfn[i]){fa[i]=-1;tarjan(i);}
        }
        rep(i,1,n){
            cout<<"TEST "<<dfn[i]<<" "<<low[i]<<endl;
        }
    }
    View Code
  • 相关阅读:
    【C】——sigprocmask 阻塞进程信号
    【C】——setjmp练习
    【程序练习】——交换两数组元素,使之和差最小
    【C】——setvbuf(scanf内存溢出问题)
    【C】——APUE小程序之递归遍历目录
    Java的原始类型(Primitive Type)
    类加载 静态加载
    行政拘留不属于行政强制措施
    行政立法主体
    行政法中三大具体行政行为
  • 原文地址:https://www.cnblogs.com/Anonytt/p/13326253.html
Copyright © 2011-2022 走看看