[USACO 2017 Dec Gold] Tutorial

Link:

USACO 2017 Dec Gold 传送门

A:

B:

将无根树转化为有根树方便计数

明显树形$dp$,转移$dp[i][j]=\prod_{k\in son} dp[k][(j+1)mod3]+dp[k][(j+2)mod3]$

#include <bits/stdc++.h>

using namespace std;
#define X first
#define Y second
typedef long long ll;
typedef pair<int,int> P;
const int MAXN=1e5+10,MOD=1e9+7;
struct edge{int nxt,to;}e[MAXN<<2];
int n,k,x,y,head[MAXN],tot;ll dp[MAXN][3];

void add_edge(int x,int y)
{e[++tot].nxt=head[x];e[tot].to=y;head[x]=tot;}
void dfs(int x,int anc)
{
    for(int i=head[x];i;i=e[i].nxt)
    {
        if(e[i].to==anc) continue;
        dfs(e[i].to,x);
        for(int j=0;j<3;j++)
            (dp[x][j]*=dp[e[i].to][(j+1)%3]+dp[e[i].to][(j+2)%3])%=MOD;
    }
}

int main()
{
    scanf("%d%d",&n,&k);
    for(int i=1;i<n;i++)
        scanf("%d%d",&x,&y),add_edge(x,y),add_edge(y,x);
    for(int i=1;i<=n;i++) 
        dp[i][0]=dp[i][1]=dp[i][2]=1;
    for(int i=1;i<=k;i++)
        scanf("%d%d",&x,&y),y--,dp[x][(y+1)%3]=dp[x][(y+2)%3]=0;
    
    dfs(1,0);
    printf("%lld",(dp[1][0]+dp[1][1]+dp[1][2])%MOD);
    return 0;
}
Problem B

C:

猜你喜欢

转载自www.cnblogs.com/newera/p/9582489.html
今日推荐