• 牛客练习赛6 C 手铐


    手铐
    思路:
    缩环+树形dp
    代码:

    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #pragma GCC optimize(4)
    #include<bits/stdc++.h>
    using namespace std;
    #define y1 y11
    #define fi first
    #define se second
    #define pi acos(-1.0)
    #define LL long long
    //#define mp make_pair
    #define pb emplace_back
    #define ls rt<<1, l, m
    #define rs rt<<1|1, m+1, r
    #define ULL unsigned LL
    #define pll pair<LL, LL>
    #define pli pair<LL, int>
    #define pii pair<int, int>
    #define piii pair<pii, int>
    #define pdd pair<double, double>
    #define mem(a, b) memset(a, b, sizeof(a))
    #define debug(x) cerr << #x << " = " << x << "
    ";
    #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    //head
     
    const int N = 1e6 + 5;
    const int MOD = 19260817;
    vector<int> g[N], G[N];
    int bcc[N], sz[N], Cnt[N];
    int dp[N];
    bool vis[N];
    int low[N], dfn[N], stk[N], tot = 0, top = 0, cnt = 0;
    inline void tarjan(int u, int fa) {
        low[u] = dfn[u] = ++tot;
        stk[++top] = u;
        vis[u] = true;
        for (int v : g[u]) {
            if(v == fa) continue;
            if(!dfn[v]) {
                tarjan(v, u);
                low[u] = min(low[u], low[v]);
            }
            else if(vis[v]) low[u] = min(low[u], dfn[v]);
        }
        if(low[u] == dfn[u]) {
            ++cnt;
            while(stk[top] != u) vis[stk[top]] = false, bcc[stk[top--]] = cnt;
            vis[stk[top]] = false, bcc[stk[top--]] = cnt;
        }
    }
    int n, m, u, v;
    int ans;
    inline void dfs(int u, int o) {
        if(Cnt[u] != 1) dp[u] = 1;
        else dp[u] = 0;
        for (int v : G[u]) {
            if(v == o) continue;
            dfs(v, u);
            ans = (ans + dp[u]*1LL*dp[v]%MOD) % MOD;
            if(Cnt[u] != 1) dp[u] = (dp[u] + dp[v]*2) % MOD;
            else dp[u] = (dp[u] + dp[v]) % MOD;
        }
    }
    int main() {
        scanf("%d %d", &n, &m);
        for (int i = 1; i <= m; ++i) scanf("%d %d", &u, &v), g[u].pb(v), g[v].pb(u);
        tarjan(1, 0);
        for (int i = 1; i <= n; ++i) {
            for (int v : g[i]) {
                if(bcc[i] == bcc[v]) continue;
                G[bcc[i]].pb(bcc[v]);
            }
            Cnt[bcc[i]]++;
        }
        dfs(1, 0);
        ans = (ans + MOD) % MOD;
        printf("%d
    ", ans);
        return 0;
    }
    
  • 相关阅读:
    leecode4:寻找两个正序数组的中位数
    leecode3:无重复字符的最长子串
    leecode2:两数相加
    KMP字符串模式匹配
    01迷宫问题
    汉诺塔问题
    微服务-基于Grpc的进程通信-Grpc异常捕获RpcException(4-4)
    React-Antd Pro增删改查
    HTTP 请求
    创业路上-1
  • 原文地址:https://www.cnblogs.com/widsom/p/11617219.html
Copyright © 2020-2023  润新知