[APIO2018]铁人两项

题目

题意:在一个无向图里面选三个点\(s\),\(c\),\(f\)

需要能够从\(s\)出发,经过\(c\),到达\(f\)点,中间不能提前经过\(f\),且需要是一个简单路径

Solution:

简单路径当然就是园方树了,想想怎么统计答案
yy一下可以发现,有一条路径\(s\)\(f\),中间能选的点就是路径上的圆点和
因为在一个点双连通分量里面,一定有一个不重复的路径到出点去。
想想怎么赋权,方点赋连接的圆点个数,圆点为-1,最后一条路径的权值和刚好就是去掉两个头的圆点个数,
然后就是个简单的dp计数了

code:

#include<bits/stdc++.h>
#define ll long long
#define R register
#define pb push_back
template<class T>
void rea(T &x)
{
    int f(0);char ch=getchar();x = 0;
    while(!isdigit(ch)){f|=ch=='-';ch=getchar();}
    while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    x = f?-x:x;
}
using namespace std;
const int N = 500005;
vector<int> I[N], e[N<<1];
ll ans;
int n, m, node, num;
int dfn[N], low[N], dfc, sta[N], tp;
int val[N<<1], siz[N<<1];
bool vis[N<<1];
void tarjan(int x)
{
    dfn[x] = low[x] = ++dfc;
    sta[++tp] = x;
    for(R int i = 0; i < I[x].size(); ++i)
    {
        if(!dfn[I[x][i]])
        {
            tarjan(I[x][i]);
            low[x] = min(low[x], low[I[x][i]]);
            if(low[I[x][i]] == dfn[x])
            {
                val[++node] = 1;
                for(R int o = 0; o != I[x][i]; --tp)
                {
                    o = sta[tp];
                    e[node].pb(o);
                    e[o].pb(node);
                    ++val[node];
                }
                e[x].pb(node), e[node].pb(x);
            }
        }
        else low[x] = min(low[x], dfn[I[x][i]]);
    }
}
void cal(int x, int fa)
{
    siz[x] = (x<=n);
    //cout<<x<<" "<<val[x]<<endl;
    for(R int i = 0; i < e[x].size(); ++i) if(e[x][i] != fa)
    {
        cal(e[x][i], x);
        ans += 2ll * siz[x] * siz[e[x][i]] * val[x];
        siz[x] += siz[e[x][i]];
    }
    ans += 2ll * siz[x] * (num-siz[x]) * val[x];
}
int main()
{
    rea(n), rea(m); node = n;
    memset(val, -1, sizeof val);
    int x, y;
    for(R int i = 1; i <= m; ++i)
        rea(x), rea(y), I[x].pb(y), I[y].pb(x);//读入用I!! 
    for(R int i = 1; i <= n; ++i) 
        if(!dfn[i]) num = dfc, tarjan(i), num = dfc-num, cal(i, 0);
    printf("%lld\n", ans);
    return 0;
}

[APIO2018]铁人两项

上一篇:Win10系统下安装PoTorch依赖包


下一篇:git LF 和 CRLF换行的问题