AtCoder Beginner Contest 222 E - Red and Blue Tree(dfs dp)

简介: AtCoder Beginner Contest 222 E - Red and Blue Tree(dfs dp)

linkkkkk

题意:

给出n个点的树和长度为m的序列a。现需要给每条边染成r e d / b l u e色,要求按照a走的路径,经过的边数r − b = k,问方案数。

思路:

首先可以通过d f s 将序列a的路径经过每条边的次数c i统计出来。这样问题就变成了从c 1 , c 2 , … … c n − 1中选择一些数和为r,剩余的数和为b,满足r − b = k

假设s u m = c 1 + c 2 + … … + c n − 1 ,那么就可以得到r + b = s u m , r − b = k,解得r = s u m + k /2

问题变成了从c 1 , c 2 , … … c n − 1中选择一些数使得和为s u m + k/2

设d p [ i ] [ j ]表示从前i个数中选,和为j的方案数。将第一维去掉,第二层循环变成倒序,跟背包一样的。

上限的话,k = 1 e 5,假设a序列的相邻两个点为直径端点,每次都走1 e 3,一共走1 e 5,每条边都是100 次,和为1 e 5,这样( k + s u m ) / 2还是1 e 5,所以取1 e 5就够用啦。

代码:

// Problem: E - Red and Blue Tree
// Contest: AtCoder - Exawizards Programming Contest 2021(AtCoder Beginner Contest 222)
// URL: https://atcoder.jp/contests/abc222/tasks/abc222_e
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;typedef unsigned long long ull;
typedef pair<ll,ll>PLL;typedef pair<int,int>PII;typedef pair<double,double>PDD;
#define I_int ll
inline ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
#define read read()
#define rep(i, a, b) for(int i=(a);i<=(b);++i)
#define dep(i, a, b) for(int i=(a);i>=(b);--i)
ll ksm(ll a,ll b,ll p){ll res=1;while(b){if(b&1)res=res*a%p;a=a*a%p;b>>=1;}return res;}
const int maxn=4e5+7,maxm=1e6+7,mod=998244353;
int n,m,k,a[110],c[1100],dp[maxm];
vector<PII>g[1100];
int dfs(int u,int fa,int e){
  if(e==u) return 1;
  for(auto t:g[u]){
    int j=t.first,id=t.second;
    if(j==fa) continue;
    if(dfs(j,u,e)){
      c[id]++;return 1;
    }
  }
  return 0;
}
int main(){
  n=read,m=read,k=read;
  rep(i,1,m) a[i]=read;
  rep(i,1,n-1){
    int u=read,v=read;
    g[u].push_back({v,i});
    g[v].push_back({u,i});
  }
  rep(i,1,m-1) dfs(a[i],-1,a[i+1]);
  int sum=0;
  rep(i,1,n-1) sum+=c[i];
  if((sum+k)%2||(sum+k)<0){
    puts("0");return 0;
  }
  dp[0]=1;
  for(int i=1;i<=n-1;i++)
    for(int j=1e5;j>=c[i];j--)
      dp[j]=(dp[j]+dp[j-c[i]])%mod;
  cout<<dp[(sum+k)/2];
  return 0;
}


目录
相关文章
Codeforces Round #192 (Div. 2) (330B) B.Road Construction
要将N个城市全部相连,刚开始以为是最小生成树的问题,其实就是一道简单的题目。 要求两个城市之间不超过两条道路,那么所有的城市应该是连在一个点上的,至于这个点就很好找了,只要找到一个没有和其他点有道路限制的即可。
40 0
HDU - 1312 Red and Black(DFS)
There is a rectangular room, covered with square tiles. Each tile is colored either red or black. A man is standing on a black tile. From a tile, he can move to one of four adjacent tiles. But he can’t move on red tiles, he can move only on black tiles. Write a program to count the number of black
84 0
|
机器学习/深度学习 Windows
Codeforces Round #748 (Div. 3) F - Red-Black Number (记忆化搜索)
Codeforces Round #748 (Div. 3) F - Red-Black Number (记忆化搜索)
101 0
|
Perl
AtCoder Beginner Contest 217 F - Make Pair (区间dp)
AtCoder Beginner Contest 217 F - Make Pair (区间dp)
122 0
AtCoder Beginner Contest 225 F.String Cards(dp)
AtCoder Beginner Contest 225 F.String Cards(dp)
90 0
|
人工智能 JavaScript BI
AtCoder Beginner Contest 222 D - Between Two Arrays(前缀和优化dp)
AtCoder Beginner Contest 222 D - Between Two Arrays(前缀和优化dp)
105 0
POJ-2488,A Knight's Journey(DFS)
POJ-2488,A Knight's Journey(DFS)
|
人工智能 vr&ar
Atcoder--Candy Distribution II--前缀和+map
题目描述 There are N boxes arranged in a row from left to right. The i-th box from the left contains Ai candies. You will take out the candies from some consecutive boxes and distribute them evenly to M children. Such being the case, find the number of the pairs (l,r) that satisfy the following:
100 0