題解 Luogu1453 城市環路

2021-08-23 14:15:36 字數 1622 閱讀 1371

給你一棵樹,強制要求一條邊只能選乙個點,並且還額外給條邊(s

,t) (s,

t)

說s,t也不能同時選,求最大貢獻

這不是擺明了那你用樹形dp切掉的節奏嗎? 設f

[u][

0/1]

f [u

][0/

1]

表示以u u

為根的字樹,

u' role="presentation">u

u點選或不選的最大貢獻

然後轉移比較顯然,

1.如果

u u

點要選,則它所有的兒子都不能選

2.如果

u' role="presentation">u

u點不選,那麼它的兒子可以選也可以不選

所以轉移式就是 f[

u][1

]=∑u

−>vf

[v][

0]f [u

][1]

=∑u−

>vf

[v][

0]

f[u][0]

=∑u−

>vm

ax(f

[v][

0],f

[v][

1]) f[u

][0]

=∑u−

>vm

ax(f

[v][

0],f

[v][

1]

)然後考慮最後的統計答案 以s

s ,

t' role="presentation">t

t兩點分別做一次dp

d

p,然後在f[

s][0

],f[

t][0

] f[s]

[0],

f[t]

[0

]中取較大值,這樣就能保證s,

t s,

t不可能同時被選了

然後就是愉快的上**環節了

#include

#include

#include

using

namespace

std;

const

int _=100005;

inline

int read()

int n,p[_],fa[_],s,t;

struct ede[_<<1];

int cnt,head[_];

double f[_][2];

void link(int u,int v);head[u]=cnt;}

int find(int x)

void dfs(int u,int fa)

}int main()

link(u,v);link(v,u);fa[find(v)]=find(u);

}double k,ans=0;

scanf("%lf",&k);

dfs(s,0);ans=f[s][0];

dfs(t,0);ans=max(ans,f[t][0]);

printf("%.1lf\n",ans*k);

return

0;}

luogu1453 城市環路 樹形dp

p1453城市環路 最開始是按騎士那道題的做法 只是這道是雙向邊 先dfs一遍判環 根節點一定在環上 然後從根節點出發 強制不選根節點的父親 因為建的是雙向邊dfs來dp的時候會重複算 所以用vis來記錄這個點有沒有走過 然後再來一遍從根節點的父親出發 不選根節點的父親的父親 不知道為啥我第二遍dp...

洛谷 P1453 城市環路

給出一幅有n個點,n條邊的無向聯通圖,每乙個點有乙個權,並給出乙個常數k,對其中一些點進行染色,且相鄰兩點的顏色不能都染,則最大的染色點權值和 k是多少.首先題目與k幾乎無關 最後乘上即可 僅僅比樹多了一條邊,因而只有乙個環,只要處理一下這個唯一環即可用樹形dp的思路來做.可以在這個環上找任意兩個相...

基環樹上dp luoguP1453 城市環路

傳送門 quq基環樹上的dp 先dp樹再dp環,然後注意環上還要記錄一維開始那個節點有沒有選,因為最後乙個節點和第乙個也不能衝突 include include include include include include define n 100005 using namespace std i...