Codeforces Round #548 (Div. 2) C. Edgy Trees(连通块+快速幂)

题目链接:http://codeforces.com/contest/1139/problem/C

【题意】连通图无环,边有黑色和红色。一个序列中代表走过的顶点,如果至少经过一条黑边则称为是好的序列。问好的序列的个数。

【分析】把全部的序列求出来,然后减去不满足的序列;即求出红边的连通块的个数;

【代码】

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn=1e5+10;
const ll mod=1e9+7;
vector<int>v[maxn];
int vis[maxn];
ll cnt,sum;

ll qpow(ll x,ll y)
{
	ll res=1;
	while(y)
	{
		if(y&1)res=(res*x)%mod;
		x=(x*x)%mod;
		y/=2;
	}
	return res;
}
void dfs(int x)
{
	if(vis[x])return;
	cnt++;vis[x]=1;
	for(int i=0;i<v[x].size();++i)
		dfs(v[x][i]);
}
int main()
{
	int n,k;scanf("%d%d",&n,&k);
	for(int i=1;i<n;++i)
	{
		int x,y,c;scanf("%d%d%d",&x,&y,&c);
		if(!c)
		{
			v[x].push_back(y);
			v[y].push_back(x);
		}
	}
	sum=qpow(n,k);
	memset(vis,0,sizeof(vis));
	for(int i=1;i<=n;++i)
	{
		cnt=0;
		if(!vis[i])
		{
			dfs(i);
			sum-=qpow(cnt,k);
			sum=(sum+mod)%mod;
		}
	}
	printf("%lld\n",sum);
}

猜你喜欢

转载自blog.csdn.net/qq_38735931/article/details/88965605