• The 2020 ICPC Asia Taipei-Hsinchu Site Programming Contest I题Critical Structures


    原题链接Critical Structures

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    #define mp make_pair
    #define newline puts("")
    
    const int maxn = 1010;
    int n,m;
    vector<int> G[maxn];
    int dfn[maxn],low[maxn],cnt = 0;
    stack<int> st;
    int ct = 0;//联通分量的数量
    // int book[maxn],num[maxn];//每个点所在环的编号以及每个环上点的数量
    vector<int> cir[maxn];//cir[k]表示第k个环上的点是哪些
    bool is_cut[maxn];//是否是割点
    int fa[maxn];
    map<pii,bool> is_bridge;
    int par[maxn],siz[maxn];
    int ans1,ans2,ans3,ans4;
    
    int getpa(int x){
        return x == par[x] ? x : par[x] = getpa(par[x]);
    }
    int gcd(int a,int b){
        return !b ? a : gcd(b,a%b);
    }
    
    void tarjan(int u,int f)//第二个参数主要是传父亲
    {
        dfn[u] = low[u] = ++cnt;
        st.push(u);
        fa[u] = f;
        int rt_num = 0;
        for (auto v : G[u])
        {
            if(!dfn[v]){
                tarjan(v,u);
                rt_num ++;
                low[u] = min(low[u],low[v]);
                if((rt_num >= 2 && fa[u] == 0) || (fa[u]!=0 && low[v] >= dfn[u])) is_cut[u] = true;
                if(low[v] > dfn[u]) {//u,v这条边是桥
                    is_bridge[mp(min(u,v),max(u,v))] = true;
                    ans2++;
                }
            }
            else if(v != fa[u])
            {
                low[u] = min(low[u],dfn[v]);
            }
        }
    
        if(dfn[u] == low[u])
        {
            ++ct;
            while(1)
            {
                int x = st.top();
                st.pop();
                cir[ct].push_back(x);
                if(x == u) break;
            }
        }
    }
    
    void Clear()
    {
        ans1 = ans2 = ans3 = 0;
        ans4 = 1;
        for (int i=1;i<=ct;i++) cir[i].clear();
        cnt = ct = 0;
        for (int i=1;i<=n;i++){
            G[i].clear();
            fa[i] = 0;
            is_cut[i] = false;
            par[i] = 0;
            siz[i] = 0;
            dfn[i] = low[i] = 0;
        }
        while(!st.empty()) st.pop();
        is_bridge.clear();
    }
    
    void solve()
    {
        scanf("%d%d", &n, &m);
        
        for (int i=1;i<=m;i++)
        {
            int u,v;
            scanf("%d%d", &u,&v);
            G[u].push_back(v),G[v].push_back(u);
        }
        tarjan(1,0);
        // for (int i=1;i<=n;i++)
        // {
        //     cout<<"i = "<<i<<" dfn = "<<dfn[i]<<" low = "<<low[i]<<endl;
        // }
        // for (int i=1;i<=n;i++) cout<<"i = "<<i<<" is_cut = "<<is_cut[i]<<endl;
        for (int i=1;i<=n;i++) ans1 += (int)is_cut[i];//割点数量要在外面加
    
        ans3 += ans2;
    
        for (int i=1;i<=n;i++) par[i] = i,siz[i] = 0;
        for (int u=1;u<=n;u++)
        {
            for (auto v : G[u])
            {
                if(v < u) continue;
                if(is_bridge[mp(u,v)]) continue;
                int f1 = getpa(u),f2 = getpa(v);
                if(f1 > f2) swap(f1,f2);
                if(f1 != f2)
                {
                    par[f2] = f1;
                    siz[f1] += siz[f2] + 1;
                }
                else siz[f1]++;
            }
        }
        for (int i=1;i<=n;i++)
        {
            int fi = getpa(i);
            if(i == fi && siz[fi] > 0) ans3++;
            ans4 = max(ans4,siz[fi]);
        }
        // cout<<"ans3 = "<<ans3<<" ans4 = "<<ans4<<endl;
        int g = gcd(ans3,ans4);
        printf("%d %d %d %d
    ",ans1,ans2,ans3/g,ans4/g);
        Clear();
    }
    int main()
    {
        // freopen("1.in","r",stdin);
        // freopen("1.out","w",stdout);
        int T;
        scanf("%d",&T);
        for(int _=1;_<=T;_++)
        {
            solve();
        }
        return 0;
    }
    
    你将不再是道具,而是成为人如其名的人
  • 相关阅读:
    程序员数学
    [topcoder]FlowerGarden
    [leetcode]Trapping Rain Water
    [leetcode]Gray Code
    [leetcode]Unique Paths II
    hdu 4112 Break the Chocolate(ceil floor)
    【转】博弈-翻硬币游戏
    POJ 3710 Christmas Game
    hdu 3590 PP and QQ
    博弈进阶
  • 原文地址:https://www.cnblogs.com/wsl-lld/p/15438284.html
Copyright © 2020-2023  润新知