洛谷 P1453 城市環路

2021-08-13 23:00:03 字數 1466 閱讀 1221

給出一幅有n個點,n條邊的無向聯通圖,每乙個點有乙個權,並給出乙個常數k,對其中一些點進行染色,且相鄰兩點的顏色不能都染,則最大的染色點權值和*k是多少.

首先題目與k幾乎無關(最後乘上即可),僅僅比樹多了一條邊,因而只有乙個環,只要處理一下這個唯一環即可用樹形dp的思路來做.

可以在這個環上找任意兩個相鄰點(用dfs找,第乙個掃過兩次的點就在環上),記為s和t,然後刪掉兩點之間的這條邊(標記一下),然後就是一棵有限制的樹了,以s為根節點,分以下兩種情況進行討論:

不對s進行染色,則之後均沒有限制.

對s進行染色,則t不能再染色.

兩種情況取最大值即可.

#include

#include

#include

#define n 100100

#define db double

using

namespace std;

struct bn

;bn bn[n*2]

;int n,ans,ll[n]

,bb,first[n]

,s,t,dp[n][2

];bool vis[n]

,get;

db k;

inline

void

add(

int u,

int v)

void

find

(int now,

int last)

find

(bn[p]

.to,now);}

}int

dfs(

int now,

bool rs,

int last)

}else

} dp[now]

[rs]

=res;

return res;

}int

main()

for(i=

1;i<=n;i++

) vis[1]

=1;find(1

,-1)

; p=first[s]

;for

(;p!=-1

;p=bn[p]

.next)

} p=first[t]

;for

(;p!=-1

;p=bn[p]

.next)}

ans=

dfs(s,0,

-1);

memset

(dp,-1

,sizeof

(dp));

dp[t][1

]=-100000000

; ans=

max(ans,

dfs(s,1,

-1)+ll[s]);

cin>>k;

printf

("%.1lf"

,k*ans)

;}

題解 Luogu1453 城市環路

給你一棵樹,強制要求一條邊只能選乙個點,並且還額外給條邊 s t s,t 說s,t也不能同時選,求最大貢獻 這不是擺明了那你用樹形dp切掉的節奏嗎?設f u 0 1 f u 0 1 表示以u u 為根的字樹,u role presentation u u點選或不選的最大貢獻 然後轉移比較顯然,1.如...

luogu1453 城市環路 樹形dp

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

基環樹上dp luoguP1453 城市環路

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