給出一幅有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...