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
  • 相关阅读:
    CodeForces Virtual Participation 记录
    Raney 引理学习笔记
    题解 CF1503A Balance the Bits
    CF1493D GCD of an Array 题解
    原根表
    LOJ6102「2017 山东二轮集训 Day1」第三题 or 51nod1355 斐波那契的最小公倍数 题解
    解决js动态改变html元素而html内容只在初末时改变的问题
    【命题逻辑实验题】求给定命题公式的真值表[C语言程序实现](支持蕴含式的运算)
    【C语言】模拟简单的《掘地求生Getting Over It》(源码)
    【C语言】英雄联盟英雄查询系统(源码)
  • 原文地址:https://www.cnblogs.com/Anonytt/p/13326253.html
Copyright © 2011-2022 走看看