E. Number of Simple Paths
题意:给一棵n个节点n条边的基环树,求图中简单路径的条数。
思路:若两个节点间的简单路径经过环,则可以有2条路可走,否则就1条, 因此可以求出多少点之间的路径步经过环就好了。可以以环为根进行dfs 判环可以用拓扑序。

#include<bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
const int inf=2e18+100;
const int maxn=2e5+100;
vector<int>g[maxn];
int in[maxn];
bool is[maxn];
int sum;
void dfs(int x,int fa)
{
	sum++;
	for(auto it:g[x])
	{
		if(is[it]||fa==it)continue;
		dfs(it,x);
	}
}
int js(int x)
{
	return x*(x-1)/2;
}
signed main()
{
	IOS
	int tt;
	cin>>tt;
	while(tt--)
	{
		int n;
		cin>>n;
		for(int i=1;i<=n;i++)g[i].clear();
		memset(in,0,sizeof(int)*(n+10));
		//memset(is,0,sizeof(bool)*(n+10));
		for(int i=1;i<=n;i++)
		{
			is[i]=1;
			int u,v;
			cin>>u>>v;
			g[u].push_back(v);
			g[v].push_back(u);
			in[u]++;in[v]++;
		}
		queue<int>q;
		for(int i=1;i<=n;i++)
		{
			if(in[i]==1)
			{
				q.push(i);
				is[i]=0;
			}
		}
		while(!q.empty())
		{
			int x=q.front();
			q.pop();
			for(auto it:g[x])
			{
				if(is[it]==0)continue;
				in[it]--;
				if(in[it]==1)
				{
					q.push(it);
					is[it]=0;
				}
			}
		}
		int ans=js(n)*2;
		for(int i=1;i<=n;i++)
		{
			if(is[i])
			{
				sum=0;
				dfs(i,0);
				ans-=js(sum);
			}
		}
		cout<<ans<<"\n";
	}
}
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐