2015-2016 ACM-ICPC Northeastern European Regional Contest (NEERC 15)C - Cactus Jubilee

题意:给一颗仙人掌,要求移动一条边,不能放在原处,移动之后还是一颗仙人掌的方案数(仙人掌:无向图,每条边只在一个环中),等价于先删除一条边,然后加一条边
题解:对于一颗仙人掌,分成两种边,1:环边:环上的边2,树边:非环上的边
考虑1.删除树边,那么只需联通两个联通快,那么方案数就是两个联通块乘积-1(除去删除的边)
2.删除环边,那么我们假设删除所有环,那么图变成了深林,方案数就是深林中每棵树任意两点连接,方案数就是全部的和,先维护一个每个环上的点有多少树边,对于每个树边联通块(大小x)共贡献是x*(x-1)/2-(x-1),对于每个环,我们先算出所有答案,按个减去每个环上点的贡献,然后考虑删除环边之后总树边联通块的贡献
bcc维护树边,并查集维护树边联通块

//#pragma GCC optimize(2)
//#pragma GCC optimize(3)
//#pragma GCC optimize(4)
//#pragma GCC optimize("unroll-loops")
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include<bits/stdc++.h>
#define fi first
#define se second
#define db double
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define vi vector<int>
#define mod 1000000007
#define ld long double
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define pli pair<ll,int>
#define pii pair<int,int>
//#define cd complex<double>
#define ull unsigned long long
//#define base 1000000000000000000
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define fin freopen("a.txt","r",stdin)
#define fout freopen("a.txt","w",stdout)
#define fio ios::sync_with_stdio(false);cin.tie(0)
inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
inline void sub(ll &a,ll b){a-=b;if(a<0)a+=mod;}
inline void add(ll &a,ll b){a+=b;if(a>=mod)a-=mod;}
template<typename T>inline T const& MAX(T const &a,T const &b){return a>b?a:b;}
template<typename T>inline T const& MIN(T const &a,T const &b){return a<b?a:b;}
inline ll qp(ll a,ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;}
inline ll qp(ll a,ll b,ll c){ll ans=1;while(b){if(b&1)ans=ans*a%c;a=a*a%c,b>>=1;}return ans;}

using namespace std;

const double eps=1e-8;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int N=100000+100,maxn=50000+10,inf=0x3f3f3f3f;

int n,m;
vi v[N];
int dfn[N],low[N],ind,pre[N],fa[N];
ll ans,sum,sz[N],tr[N];
map<pii,bool>tree;
int Find(int x){return fa[x]==x?x:fa[x]=Find(fa[x]);}
void tarjan(int u,int f)
{
    sz[u]=1;
    dfn[u]=low[u]=++ind;
    for(int x:v[u])
    {
        if(x==f)continue;
        if(!dfn[x])
        {
            tarjan(x,u);
            sz[u]+=sz[x];
            low[u]=min(low[u],low[x]);
            if(low[x]>dfn[u])tree[mp(u,x)]=tree[mp(x,u)]=1,ans+=sz[x]*(n-sz[x])-1;
        }
        else if(dfn[x]<dfn[u])low[u]=min(low[u],dfn[x]);
    }
}
void dfs(int u,int f)
{
    dfn[u]=1;
    for(int x:v[u])
    {
        if(x==f)continue;
        if(!dfn[x]&&tree.find(mp(u,x))!=tree.end())//tree edge
        {
            dfs(x,u);
            int fx=Find(u),fy=Find(x);
            if(fx!=fy)fa[fx]=fy,tr[fy]+=tr[fx];
        }
    }
}

void dfs1(int u,int f)
{
    dfn[u]=1;
    for(int x:v[u])
    {
        if(x==f)continue;
        if(!dfn[x])pre[x]=u,dfs1(x,u);
        else if(dfn[x]==1)
        {
            ll res=sum,co=0,p=0;
            for(int now=u;now!=x;now=pre[now])
            {
                int fx=Find(now);
                co+=tr[fx],p++,res-=1ll*(tr[fx]-1)*tr[fx]/2-(tr[fx]-1);
            }
            int fx=Find(x);
            co+=tr[fx],p++,res-=1ll*(tr[fx]-1)*tr[fx]/2-(tr[fx]-1);
            res=(res+1ll*(co-1)*co/2-(co-1)-1)*p;
//            printf("%d %d %lld %lld %lld***\n",u,x,co,p,res);
            ans+=res;
        }
    }
    dfn[u]=2;
}
int main()
{
    freopen("cactus.in","r",stdin);
    freopen("cactus.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)fa[i]=i,tr[i]=1;
    for(int i=0;i<m;i++)
    {
        int x,k,last=0;scanf("%d",&k);
        while(k--)
        {
            scanf("%d",&x);
            if(last)v[last].pb(x),v[x].pb(last);
            last=x;
        }
    }
    tarjan(1,-1);
//    printf("%lld\n",ans);
    memset(dfn,0,sizeof dfn);
    for(int i=1;i<=n;i++)if(!dfn[i])dfs(i,-1);
    for(int i=1;i<=n;i++)
    {
        if(fa[i]==i)
        {
            sum+=1ll*(tr[i]-1)*tr[i]/2-(tr[i]-1);
//            printf("%d %d\n",i,tr[i]);
        }
    }
    memset(dfn,0,sizeof dfn);
    dfs1(1,-1);
    printf("%lld\n",ans);
    return 0;
}
/********************
9 4
5 1 2 3 4 5
4 2 8 7 4
2 6 7
2 8 9
********************/

原文地址:https://www.cnblogs.com/acjiumeng/p/9966168.html

时间: 2024-10-08 11:30:54

2015-2016 ACM-ICPC Northeastern European Regional Contest (NEERC 15)C - Cactus Jubilee的相关文章

2017-2018 ACM-ICPC Northern Eurasia (Northeastern European Regional) Contest (NEERC 17)

2017-2018 ACM-ICPC Northern Eurasia (Northeastern European Regional) Contest (NEERC 17) A 题意:有 n 个时刻,第 i 个时刻要么会在 (xi,yi) 生成一个半径为 yi 的圆,要么射击 (xi,yi) 这个点,如果该点在某个圆内则把对应圆删除并输出该圆的标号,否则输出 -1 .任意时刻圆之间不会相交(可以相切). \(n \le 2*10^5, -10^9 \le x_i,y_i \le 10^9, y

2016-2017 ACM-ICPC Northeastern European Regional Contest (NEERC 16)

D:上下界费用流 将每个点和每个长度D的区间看作边,限制条件看作流量上下界,差分建图,无源汇最大费用费用流,非常巧妙的使用了差分建图. #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<queue> #define N 100003 #define inf 2000000000 #defi

ACM ICPC Central Europe Regional Contest 2013 Jagiellonian University Krak&#243;w

ACM ICPC Central Europe Regional Contest 2013 Jagiellonian University Kraków Problem A: Rubik's RectangleProblem B: What does the fox say?Problem C: Magical GCDProblem D: SubwayProblem E: EscapeProblem F: DraughtsProblem G: History courseProblem H: C

2016 ACM/ICPC Asia Regional Shenyang Online 1009/HDU 5900 区间dp

QSC and Master Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 859    Accepted Submission(s): 325 Problem Description Every school has some legends, Northeastern University is the same. Enter

2016 ACM/ICPC Asia Regional Shenyang Online 1007/HDU 5898 数位dp

odd-even number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 388    Accepted Submission(s): 212 Problem Description For a number,if the length of continuous odd digits is even and the length

hdu 5868 2016 ACM/ICPC Asia Regional Dalian Online 1001 (burnside引理 polya定理)

Different Circle Permutation Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 208    Accepted Submission(s): 101 Problem Description You may not know this but it's a fact that Xinghai Square is

HDU 5889 Barricade 【BFS+最小割 网络流】(2016 ACM/ICPC Asia Regional Qingdao Online)

Barricade Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 997    Accepted Submission(s): 306 Problem Description The empire is under attack again. The general of empire is planning to defend his

2016 ACM/ICPC Asia Regional Shenyang Online 1003/HDU 5894 数学/组合数/逆元

hannnnah_j’s Biological Test Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 802    Accepted Submission(s): 269 Problem Description hannnnah_j is a teacher in WL High school who teaches biolog

2016 ACM/ICPC Asia Regional Dalian Online 1002/HDU 5869

Different GCD Subarray Query Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 681    Accepted Submission(s): 240 Problem Description This is a simple problem. The teacher gives Bob a list of prob