P2495 SDOI2011 消耗戰 虛樹

2022-05-20 08:52:05 字數 1429 閱讀 9753

題意:一棵樹上給定點集,求到根的最小割。

每次詢問只和給定的點集以及它們的lca有關係,那麼把這些點拿出來建立一棵樹。再進行樹dp。具體操作把所有詢問點按照dfn排序,再用乙個棧進行維護建樹。彈棧的時候並不是每個點都和棧中第二個元素連邊,有可能最後乙個彈棧點和新的lca連邊。dp轉移時需要查詢樹鏈的最小邊,這裡用倍增做。

#include#define cmin(a,b) (a>b?a=b:a)

using

namespace

std;

typedef

long

long

ll;const

int n=5e5+10

;const

int m=2.5e5+10

;int head[n],ver[2*m],edge[2*m],nex[2*m],tot=1

;inline

void add(int x,int y,int

z) int d[n],f[n][25],min[n][25

],dfn[n],num,_t,n;

void dfs(int x)

dfs(y);

}}int lca(int x,int

y) int minedge(int x,int y)

cmin(res,min[x][

0]);cmin(res,min[y][0

]);

return

res;

}bool cmp(int x,int y)

intstk[n],top,fa[n],a[n],in_deg[n],cntq;

void build()

if(dfn[stk[top]]>dfn[lca])fa[stk[top--]]=lca,++in_deg[lca];

if(stk[top]!=lca)stk[++top]=lca;

stk[++top]=a[i];

}while(top>1)}

ll dp[n];

int isq[n],clear[n],cnt;//

isq:詢問點,clear:等待清空

ll solve()

ll ans=dp[1

];

for(int i=0;i0;//

清空dp陣列

for(int i=0;i0;//

清空詢問點標記

return

ans;

}int

main()

_t=log(n+0.5)/log(2);//

init

d[1]=1;//

init

dfs(1

); scanf("%d

",&m);

while(m--)

return0;

}

view code

虛樹 P2495 SDOI2011 消耗戰

好久沒有學習新的知識了。今天我學習了一下虛樹。虛樹就是乙個不存在的樹。用來簡化問題。它只包括一些關鍵點和他的lca 我們來看看上面這一道題 給出一棵樹,含有邊權。每次詢問給出k個點,然後詢問每個點與根斷開的最小代價。因為資料的關係肯定沒法直接dp過去的。首先我們可以發現可以與根到其他點的路徑沒有關係...

P2495 SDOI2011 消耗戰 虛樹

這是我做的第一道虛樹題啊,趕腳不錯.其實虛樹也沒什麼奇怪的,就是每棵樹給你一些點,讓你多次查詢,但是我不想每次都o n 所以我們每次針對給的點建一棵虛樹,只包含這些點和lca,然後在這棵虛樹上進行樹形dp,維護每個點的最小連邊權值,這樣的複雜度就會降低不少.這裡我寫了兩種寫法 其實都是抄的 一種是正...

SDOI2011 消耗戰 虛樹

有m次詢問,又有詢問的總的點數之和是小於等於5e5的,所以,其實就是乙個虛樹的模板了,直接用棧維護乙個虛樹即可。期間寫的時候出現了一點問題 初始化的時候,不只是要初始那些輸入的k個結點,還有k個結點的lca的衍生結點也是需要初始化的,所以初始化不到位會mle和tle的,這裡不要忘。include i...