zoukankan      html  css  js  c++  java
  • Gym 100342I Travel Agency (Tarjan)

    题意读懂了就好做了,就是求一下点双连通分量。维护一下一颗子树的结点数,对于一个结点当u是割点的时候,

    统计一下u分割的连通分量v,每得到一个连通分量的结点数cnt(v)和之前连通分量结点数sum相乘一下就好。最后加一下和u的子树上的连通分量总数和其它的结点的乘积。

    B,C中其中一者可以是A,所有最后还要加上n-1。

    补下以前的题

    #include<bits/stdc++.h>
    using namespace std;
    int n,m;
    const int maxn = 20005;
    vector<int> G[maxn];
    #define PB push_back
    
    int dfn[maxn],low[maxn],dfs_clock,ans[maxn],cnt[maxn];
    
    void tarjan(int u,int fa = -1)
    {
        dfn[u] = low[u] = ++dfs_clock;
        cnt[u] = 1; ans[u] = 0;
        int sum = 0;
        for(int i = 0; i < G[u].size(); i++){
            int v = G[u][i];
            if(!dfn[v]){
                tarjan(v,fa);
                if(low[v]>=dfn[u]){
                    ans[u] += sum*cnt[v];
                    sum += cnt[v];
                }
                low[u] = min(low[v],low[u]);
                cnt[u] += cnt[v];
            }else if(v != fa && dfn[v] < dfn[u] ) { low[u] = min(low[u],dfn[v]); }
        }
        ans[u] += (n-sum-1)*sum;
    
    }
    
    int main()
    {
        freopen("travel.in","r",stdin);
        freopen("travel.out","w",stdout);
        cin>>n>>m;
        for(int i = 0; i < m; i++){
            int u,v; scanf("%d%d",&u,&v);
            G[u].PB(v); G[v].PB(u);
        }
        tarjan(1);
        for(int i = 1; i <= n; i++) printf("%d
    ",ans[i]+n-1);
        return 0;
    }
  • 相关阅读:
    java实现复制网站内容
    java实现复制网站内容
    java实现递归连续数
    java实现递归连续数
    java实现递归连续数
    java实现递归连续数
    java实现递归连续数
    java实现串中找数字
    java实现串中找数字
    java实现串中找数字
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4770915.html
Copyright © 2011-2022 走看看