Codeforces Round #548 (Div. 2) C. Edgy Trees

You are given a tree (a connected undirected graph without cycles) of ? vertices. Each of the ?−1 edges of the tree is colored in either black or red.

You are also given an integer ?. Consider sequences of ? vertices. Let’s call a sequence [?1,?2,…,??] good if it satisfies the following criterion:

We will walk a path (possibly visiting same edge/vertex multiple times) on the tree, starting from ?1 and ending at ??.
Start at ?1, then go to ?2 using the shortest path between ?1 and ?2, then go to ?3 in a similar way, and so on, until you travel the shortest path between ??−1 and ??.
If you walked over at least one black edge during this process, then the sequence is good.

Consider the tree on the picture. If ?=3 then the following sequences are good: [1,4,7], [5,5,3] and [2,3,7]. The following sequences are not good: [1,4,6], [5,5,5], [3,7,3].

There are ?? sequences of vertices, count how many of them are good. Since this number can be quite large, print it modulo 109+7.

Input
The first line contains two integers ? and ? (2≤?≤105, 2≤?≤100), the size of the tree and the length of the vertex sequence.

Each of the next ?−1 lines contains three integers ??, ?? and ?? (1≤??,??≤?, ??∈{0,1}), where ?? and ?? denote the endpoints of the corresponding edge and ?? is the color of this edge (0 denotes red edge and 1 denotes black edge).

Output
Print the number of good sequences modulo 109+7.

Examples
inputCopy
4 4
1 2 1
2 3 1
3 4 1
outputCopy
252
inputCopy
4 6
1 2 0
1 3 0
1 4 0
outputCopy
0
inputCopy
3 5
1 2 1
2 3 0
outputCopy
210
Note
In the first example, all sequences (44) of length 4 except the following are good:

[1,1,1,1]
[2,2,2,2]
[3,3,3,3]
[4,4,4,4]
In the second example, all edges are red, hence there aren’t any good sequences.

题意:给定一棵树,树上的边有红色和黑色两种颜色。假设一个长度为k的序列<a1,a2,…,ak>,表示从a1开始依次走到序列中的点直到ak,如果在走整个序列的过程中至少经过一次黑色的边,表示这个序列是好的(good sequence)。现在给定一个这个长度k,输出有多少种满足好的序列的个数。

思路:因为是在树上,当经过一条黑色的边后走访其余的点全都是满足good sequence了。因此统计每一个全是红色边的子树的点数,设为w,仅在这颗子树中互相走访的序列个数为wk。统计出所有的wk最后在nk将它们的和减去就行了。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#define INF 0x3f3f3f3f
#define ll long long
#define ull unsigned long long
#define lowbit(x) (x&(-x))
#define eps 0.00000001
#define PI acos(-1)
#define ms(x,y) memset(x, y, sizeof(x))
using namespace std;

const ll mod = 1e9+7;
const int maxn = 1e5+7;
struct Edge {
    int to, x;
    Edge(int a=0,int _x=0):to(a), x(_x){}
};
vector <Edge> e[maxn];
int n, k;


int cnt;
int vis[maxn];
void dfs(int u)
{
    vis[u] = 1;
    cnt ++;
    for(int i=0;i<e[u].size();i++)
        if(!e[u][i].x && !vis[e[u][i].to])
            dfs(e[u][i].to);
}

ll qm(ll a, int b)
{
    ll res = 1, base = a;
    while(b)
    {
        if(b&1) res = (res * base) % mod;
        base = (base * base) % mod;
        b >>= 1;
    }
    return res % mod;
}

int main()
{
    int u, v, x;
    scanf("%d%d", &n, &k);
    for(int i=1;i<n;i++)
    {
        scanf("%d%d%d", &u, &v, &x);
        e[u].push_back(Edge(v, x));
        e[v].push_back(Edge(u, x));
    }
    
    ll tot = 0;
    for(int i=1;i<=n;i++)
    {
        cnt  = 0;
        if(!vis[i])
            dfs(i);
        tot = (tot + qm(cnt, k)) % mod;
    }
    
    printf("%lld\n", (qm(n, k) - tot + mod) % mod);
    
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值