• [loj 2587] 「APIO2018」铁人两项


    「APIO2018」铁人两项

    LOJ 2587

    1

    3

    2

    题目大意

    给出一个 (n) 个点,(m) 条边的无向图,问存在多少个互异三元组 ((s, c, f)) 满足存在两条分别从 (s)(c)(c)(f) ,且点不重复的路径

    数据范围

    (n le 100000, m le 200000)

    时空限制

    1000ms, 1024MB

    分析

    圆方树模板题

    考虑对于一对 ((s, f)) ,所有可能的 (c) 就是它们路径上点双里的点,而且不算 (s)(f) ,建出圆方树,考虑路径上一个点双的贡献是它的大小,而割点会重复统计,所以让圆方树上圆点贡献为 (-1) ,方点贡献为它的 (size) 那么一个点的计算次数就是通过它的圆点对数,树形DP即可

    总结

    最开始想的是枚举 (c) 算贡献,所以发现不可做时要更换思路啊...

    Code

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    inline char nc()
    {
    	static char buf[100000], * l = buf, * r = buf;
    	if (l == r) r = (l = buf) + fread(buf, 1, 100000, stdin);
    	if (l == r) return EOF;
    	return *l++;
    }
    template<class T> void read(T & x)
    {
    	x = 0; int f = 1, ch = nc();
    	while (!isdigit(ch))
    	{
    		if (ch == '-') f = -1;
    		ch = nc();
    	}
    	while (isdigit(ch))
    	{
    		x = x * 10 - '0' + ch;
    		ch = nc();
    	}
    	x *= f;
    }
    
    typedef long long ll;
    
    const int maxn = 100000 + 5;
    const int maxm = 200000 + 5;
    const int maxe = maxm * 2;
    const int maxnode = maxn * 2;
    
    int n, m;
    
    struct edge
    {
        int to, nex;
        edge(int to = 0, int nex = 0) : to(to), nex(nex) {}
    } g[maxe];
    int head[maxn];
    int ecnt;
    vector<int> adj[maxnode];
    
    inline void addedge(int u, int v)
    {
        g[ecnt] = edge(v, head[u]), head[u] = ecnt++;
        g[ecnt] = edge(u, head[v]), head[v] = ecnt++;
    }
    inline void adde(int u, int v)
    {
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    
    int dfc, dfn[maxn], low[maxn];
    int top, sta[maxn];
    int bcnt;
    int bccsiz[maxn];
    
    int val[maxnode];
    int siz[maxnode];
    
    void tarjan(int u, int fa)
    {
        low[u] = dfn[u] = ++dfc;
        sta[++top] = u;
        siz[u] = 1;
        for(int i = head[u]; ~ i; i = g[i].nex)
        {
            int v = g[i].to;
            if(v != fa)
            {
                if(!dfn[v])
                {
                    tarjan(v, u);
                    low[u] = min(low[u], low[v]);
                    if(low[v] >= dfn[u])
                    {
                        bcnt++;
                        adde(n + bcnt, u);
                        bccsiz[bcnt] = 1;
                        while(true)
                        {
                            int x = sta[top--];
                            adde(n + bcnt, x);
                            bccsiz[bcnt]++;
                            siz[bcnt + n] += siz[x];
                            if(x == v) break;
                        }
                        siz[u] += siz[bcnt + n];
                        val[bcnt + n] = bccsiz[bcnt];
                    }
                }
                else low[u] = min(low[u], dfn[v]);
            }
        }
    }
    
    int all;
    ll an;
    
    void dfs(int u, int fa)
    {
        ll re = (ll)(all - siz[u]) * siz[u] * 2;
        int t = int(u <= n);
        for(unsigned int i = 0; i < adj[u].size(); ++i)
        {
            int v = adj[u][i];
            if(v != fa)
            {
                dfs(v, u);
                re += (ll)t * siz[v] * 2;
                t += siz[v];
            }
        }
        an += re * val[u];
    }
    
    void solve()
    {
        for(int i = 1; i <= n; ++i)
        {
            val[i] = -1;
        }
        for(int i = 1; i <= n; ++i) if(!dfn[i])
        {
            tarjan(i, -1);
            all = siz[i], dfs(i, -1);
        }
        cout << an << endl;
    }
    
    int main()
    {
    //    freopen("testdata.in", "r", stdin);
        read(n), read(m);
        memset(head, -1, sizeof(head));
        for(int i = 1; i <= m; ++i)
        {
            int u, v; read(u), read(v);
            addedge(u, v);
        }
        solve();
    	return 0;
    }
    
    
  • 相关阅读:
    一.在Linux中for和cat遍历文件内容出现no space
    六.安装jdk(基于Centos7安装)
    五·管理mysql
    四·安装mysql-5.7.16-linux-glibc2.5-x86_64.tar.gz(基于Centos7源码安装)
    ArcGIS api for javascript——图形-增加图形到地图
    ArcGIS api for javascript——图层-创建定制的切片图层类型的图层
    ArcGIS api for javascript——图层-创建WMS图层类型的图层
    ArcGIS api for javascript——地图配置-定制缩放动画,定制缩放框
    ArcGIS api for javascript——地图配置-定制缩放动画
    ArcGIS api for javascript——地图配置-滑动器的刻度线、方向、大小的改变
  • 原文地址:https://www.cnblogs.com/ljzalc1022/p/10229446.html
Copyright © 2020-2023  润新知