ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

E - Number of Simple Paths

2021-03-12 23:03:04  阅读:163  来源: 互联网

标签:Paths fa Simple ll 路径 Number int find define


一个图,n个点,n条边,没有重边和自环。

那么多出的一条边必定使他成为基环树。

要求去计算简单路径的个数。

简单路径:与方向无关的路径。

又因为在树上,两点的路径唯一确定,那么路径仅仅与起点与终点有关。

也就是C(2,n)这样。

但是如果路径经过环,那么中间经过环的部分就可以有两种走法。

也就是说答案=走过环的路径+没有走过环的路径

假设所有路径都过环,再减去树内的路径

通过拓扑排序和并查集的方式,将这个基环树划分为几个子树。

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define MAX 1000001
#define inf 0x3f3f3f3f
#define ll long long
#define MAX 1000001
const ll N = 2e5+7;
const ll mod = 1e9+7;
using namespace std;
ll deg[N],cnt,q[N],fa[N],num[N],n;
vector<int> G[N];
int find(int u){
    return fa[u]==u?u:fa[u]=find(fa[u]);
}
void unite(int u,int v){
    u=find(u),v=find(v);
    if(u==v)    return ;
    fa[u]=v;
    num[v]+=num[u];
}
int main(){
    int t;scanf("%d",&t);
    while(t--){
        scanf("%lld",&n);
        //初始化 
        cnt=0;
        for(int i=1;i<=n;++i){
            G[i].clear();
            num[i]=1;fa[i]=i;deg[i]=0;
        }
        
        for(int i=1;i<=n;++i){
            int u,v;
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
            G[v].push_back(u);
            deg[u]++;deg[v]++;
        }
        
        //找根 
        for(int i=1;i<=n;++i)
            if(deg[i]==1)    q[++cnt]=i;
        //划分出各个基环上的树 
        for(int i=1;i<=cnt;++i){
            int u=q[i];
            for(int j=0;j<G[u].size();++j){
                int v=G[u][j];
                unite(u,v); 
                deg[v]--;
                if(deg[v]==1)    q[++cnt]=v;
            }
        }
        
        ll ans=n*(n-1);
        for(int i=1;i<=n;++i){
            if(i==fa[i]){
                ans=ans-(1ll*num[i]*(num[i]-1)/2);
            }
        }
        printf("%lld\n",ans);
    }
    return 0; 
}

 

标签:Paths,fa,Simple,ll,路径,Number,int,find,define
来源: https://www.cnblogs.com/PdrEam/p/14526881.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有