返回顶部

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;
    }
    
posted @ 2020-11-26 22:20  Rayotaku  阅读(134)  评论(0编辑  收藏  举报