当前位置:网站首页>[noi Simulation Competition] send (tree DP)

[noi Simulation Competition] send (tree DP)

2022-06-24 08:59:00 DD(XYX)

Topic

 Insert picture description here
 Insert picture description here

Answer key

Finding the nearest transfer station can be directly transformed into matching any transfer station .

Tree form DP, There's nothing to say about this .

The main thing is how to design the state .

The positive solution and the state designed by most people are very , So you don't need anything else to go through .

But I designed a bad one DP:

Make d p 1 [ i ] [ j ] dp_1[i][j] dp1[i][j] It means that i i i In the subtree , There are j j j Keys unowned , The minimum value of the sum of all edge contributions in the subtree . d p 2 [ i ] [ j ] dp_2[i][j] dp2[i][j] It means that i i i subtree Outside All in all j j j Three key points should be connected , subtree Inside The minimum value of the sum of all edge contributions .

Merge two subtrees x , y x,y x,y when , Two DP You can carry them separately , besides , d p 2 [ x ] [ i ] dp_2[x][i] dp2[x][i] Can also from d p 2 [ x / y ] [ i + j ] + d p 1 [ y / x ] [ j ] + . . . dp_2[x/y][i+j]+dp_1[y/x][j]+... dp2[x/y][i+j]+dp1[y/x][j]+... Turn around . Greedy thought , We just need external needs to swallow up ownerless needs , At this time, the key points of ownerlessness must not be added . Finally, we will discuss how to set up a transfer station at the root of the subtree .

But there's a small problem : The number of states of each subtree is equal to O ( n ) O(n) O(n) Of , although d p 1 dp_1 dp1 The complexity of can be guaranteed to be O ( n 2 ) O(n^2) O(n2) , however d p 2 dp_2 dp2 yes O ( n 3 ) O(n^3) O(n3) Of . Use the greedy technique again : The total demand outside the subtree will not exceed the total number of key points in the subtree , Otherwise, the transfer station can be moved up .

Time complexity O ( n 2 ) O(n^2) O(n2) .

CODE

#include<map>
#include<set>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<random>
#include<bitset>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
#pragma GCC optimize(2)
using namespace std;
#define MAXN 3005
#define LL long long
#define ULL unsigned long long
#define ENDL putchar('\n')
#define DB double
#define lowbit(x) (-(x) & (x))
#define FI first
#define SE second
#define PR pair<int,int>
int xchar() {
    
	static const int maxn = 1000000;
	static char b[maxn];
	static int pos = 0,len = 0;
	if(pos == len) pos = 0,len = fread(b,1,maxn,stdin);
	if(pos == len) return -1;
	return b[pos ++];
}
// #define getchar() xchar()
LL read() {
    
	LL f = 1,x = 0;int s = getchar();
	while(s < '0' || s > '9') {
    if(s<0)return -1;if(s=='-')f=-f;s = getchar();}
	while(s >= '0' && s <= '9') {
    x = (x<<1) + (x<<3) + (s^48);s = getchar();}
	return f*x;
}
void putpos(LL x) {
    if(!x)return ;putpos(x/10);putchar((x%10)^48);}
void putnum(LL x) {
    
	if(!x) {
    putchar('0');return ;}
	if(x<0) putchar('-'),x = -x;
	return putpos(x);
}
void AIput(LL x,int c) {
    putnum(x);putchar(c);}

int n,m,s,o,k;
int hd[MAXN],nx[MAXN<<1],v[MAXN<<1],w[MAXN<<1],cne;
void ins(int x,int y,int z) {
    
	nx[++cne] = hd[x]; v[cne] = y; hd[x] = cne; w[cne] = z;
}
LL dp[MAXN][MAXN],dp2[MAXN][MAXN],td[MAXN],td2[MAXN];
int siz[MAXN],ct[MAXN],C;
void dfs(int x,int ff) {
    
	siz[x] = ct[x];
	for(int i = 0;i <= n;i ++) dp[x][i] = 1e18,dp2[x][i] = 1e18;
	dp[x][0] = C; dp[x][ct[x]] = 0;
	for(int i = 0;i <= ct[x];i ++) dp2[x][i] = C;
	for(int ii = hd[x];ii;ii = nx[ii]) {
    
		int y = v[ii],W = w[ii]; if(y == ff) continue;
		dfs(y,x);
		for(int i = siz[x];i >= 0;i --) {
    
			td[i] = dp[x][i],td2[i] = dp2[x][i];
			dp[x][i] = 1e18; dp2[x][i] = 1e18;
		}
		for(int i = siz[x];i >= 0;i --) {
    
			for(int j = siz[y];j >= 0;j --) {
    
				dp[x][i+j] = min(dp[x][i+j],td[i] + dp[y][j] + W*1ll*j);
				dp2[x][i+j] = min(dp2[x][i+j],td2[i] + dp2[y][j] + W*1ll*j);
			}
			for(int j = 0;j <= siz[y] && j <= i;j ++) {
    
				dp2[x][i-j] = min(dp2[x][i-j],td2[i] + dp[y][j] + W*1ll*j);
			}
		}
		for(int i = siz[y];i >= 0;i --) {
    
			for(int j = 0;j <= siz[x] && j <= i;j ++) {
    
				dp2[x][i-j] = min(dp2[x][i-j],dp2[y][i] + W*1ll*i + td[j]);
			}
		}
		siz[x] += siz[y];
	}
	LL mn = 1e18;
	for(int i = 0;i <= siz[x];i ++) mn = min(mn,dp[x][i] + C);
	dp2[x][0] = dp[x][0] = min(min(dp2[x][0],dp[x][0]),mn);
	for(int i = 1;i <= siz[x];i ++) dp2[x][i] = min(dp2[x][i],mn);
	return ;
}
int main() {
    
	freopen("post.in","r",stdin);
	freopen("post.out","w",stdout);
	n = read(); m = read(); C = read();
	for(int i = 1;i < n;i ++) {
    
		s = read();o = read();k = read();
		ins(s,o,k); ins(o,s,k);
	}
	for(int i = 1;i <= m;i ++) {
    
		ct[read()] ++;
	}
	dfs(1,0);
	AIput(dp[1][0],'\n');
	return 0;
}
原网站

版权声明
本文为[DD(XYX)]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/175/202206240626417676.html