Luogu P3647 連珠線 題解報告

2022-04-28 20:21:09 字數 2386 閱讀 6693

題目傳送門

【題目大意】

【思路分析】

好的這道題目我在換根dp的部分卡了乙個世紀……所以設狀態真的很重要,我因為狀態設的不好,然後換根的時候就很複雜qaq

我來講一下乙個學長

的做法叭qwq

最後的連線情況是一棵樹,首先我們要發現兩個性質,就是在樹中藍線一定是連線在父子之間,並且連續的一段藍線一定為偶數。

因為藍線是刪除了一條紅線之後加入的,所以不可能存在類似下左圖這種形狀的連線方式,下右圖這種連線方式才是合法的

然後因為每次新增兩根藍線(我們稱這兩根藍線為一組),所以顯然連續的藍線數量必須是偶數。

總體思路是設1為根先dp一遍,然後換根,重要的是如何設狀態可以在換根的時候方便轉移。

我們設$f[x]$表示以$x$為根的子樹的最大分數,注意此時這個子樹可以單獨出來,即子樹中的藍線數量為偶數。

$d[x][0]$結構體記錄與$x$相連的,以$x$為根的子樹中的邊中最大的邊的值和這條邊連線的$x$的兒子,$d[x][1]$記錄次大值及對應的兒子。當然記錄的值保證更優,即記錄下的兒子$y$在下左圖的連線方式比下右圖的連線方式更優。

轉移見**及注釋

【**實現】

1 #include2 #include3 #include4 #include5 #include6 #include7

#define g() getchar()

8#define rg register

9#define go(i,a,b) for(rg int i=a;i<=b;i++)

10#define back(i,a,b) for(rg int i=a;i>=b;i--)

11#define db double

12#define ll long long

13#define il inline

14#define pf printf

15#define mem(a,b) memset(a,b,sizeof(a))

16#define e(i,x) for(rg int i=hd[x];i;i=e[i].nxt)

17#define t(i) e[i].to

18#define w(i) e[i].w

19using

namespace

std;

20int

fr()

27while(ch>='

0'&&ch<='

9') w=(w<<1)+(w<<3)+ch-'

0',ch=g();

28return w*q;29}

30const

int n=200002;31

const

int inf=1e9+7;32

intn,ed,hd[n],f[n],ans;

33struct

edgee[n<<1

];36

struct

noded[n][2

];39 il void build(rg int u,rg int v,rg int

w);hd[u]=ed;

41swap(u,v);

42 e[++ed]=(edge);hd[u]=ed;

43return;44

}45 il void update(rg int x,rg int y,rg int

w);47

else

if(w>d[x][1].v) d[x][1]=(node);

48return;49

}50 il void dp(rg int x,rg int

fa) return;59

}60 il void dfs(rg int x,rg int

fa)72

return;73

}74intmain()

82 dp(1,0);ans=-inf;dfs(1,0

);83 pf("

%d\n

",ans);

84return0;

85 }

**戳這裡

P3647 連珠線 題解

portal 首先它從遊戲開始到結束,是始終只有乙個連通塊的。對於連紅邊,那就直接連就可以了。對於連藍邊,我們首先需要找到一對有紅邊直接相連的點,然後拆散它們把新點插進去,然後仍然是乙個連通塊。稍微等價理解一下,發現其實就是一次連紅邊是從當前連通塊伸出去乙個點 而連藍邊肯定是一下就有兩條,我們把這次...

P3647 APIO2014 連珠線 換根DP

傳送門 我們通過分析 手動模擬能夠發現,藍線的形態只有兩種 son u 1 u son u 2 和 son u u fa u 對於每乙個節點,要麼是乙個藍線的中點,要麼就是藍線的端點,所以我們設 f u 0 表示 u 為藍線端點時的答案,f u 1 表示 u 作為中點時的答案 轉移方程如下 f u ...

Luogu P1208 混合牛奶

這個題目直接開個結構體按 排序,然後一直加加加,就可以了。典型的貪心。include include include include include include using namespace std int i,m,n,j,k,ans struct mana 5001 bool cmp man...