Codeforces Round #686 (Div. 3) E. Number of Simple Paths (思维,图,bfs)
-
题意:有一个\(n\)个点,\(n\)条边的图,问你长度至少为\(1\)的简单路径有多少条.
-
题解:根据树的性质,我们知道这颗树一定存在一个环,假如一棵树没有环,那么它的所有长度不小于\(1\)的简单路径数一定是\(\frac{n*(n-1)}{2}\),因为每个点都可以和其他任意一个点形成一条路径,除以\(2\)表示去除反向的边的个数,而环上的点到其他点的个数就不用除以\(2\),因为环上的点到其他的点都一定有两种不同的路径可以走,所以路径数为\(n*(n-1)\),我们可以记录不在环上的节点数(从入度为\(1\)的点开始,不断向下累加贡献),最后枚举每个点,求答案即可.
-
代码:
#define int long long int t; int n; int a,b; int sz[N]; signed main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); cin>>t; while(t--){ cin>>n; vector< set<int> > v(n+10); rep(i,1,n){ cin>>a>>b; v[a].insert(b); v[b].insert(a); sz[i]=1; } queue<int> q; rep(i,1,n) if(v[i].size()==1) q.push(i); while(!q.empty()){ int top=q.front(); q.pop(); int ne=*v[top].begin(); sz[ne]+=sz[top]; sz[top]=0; v[top].clear(); v[ne].erase(top); if(v[ne].size()==1) q.push(ne); } int ans=0; rep(i,1,n){ ans+=sz[i]*(sz[i]-1)/2; ans+=sz[i]*(n-sz[i]); } cout<<ans<<'\n'; } return 0; }
𝓐𝓬𝓱𝓲𝓮𝓿𝓮𝓶𝓮𝓷𝓽 𝓹𝓻𝓸𝓿𝓲𝓭𝓮𝓼 𝓽𝓱𝓮 𝓸𝓷𝓵𝔂 𝓻𝓮𝓪𝓵
𝓹𝓵𝓮𝓪𝓼𝓾𝓻𝓮 𝓲𝓷 𝓵𝓲𝓯𝓮