国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

bzoj2286 [Sdoi2011]消耗戰

2019-11-08 02:36:03
字體:
來源:轉載
供稿:網友

Description

在一場戰爭中,戰場由n個島嶼和n-1個橋梁組成,保證每兩個島嶼間有且僅有一條路徑可達。現在,我軍已經偵查到敵軍的總部在編號為1的島嶼,而且他們已經沒有足夠多的能源維系戰斗,我軍勝利在望。已知在其他k個島嶼上有豐富能源,為了防止敵軍獲取能源,我軍的任務是炸毀一些橋梁,使得敵軍不能到達任何能源豐富的島嶼。由于不同橋梁的材質和結構不同,所以炸毀不同的橋梁有不同的代價,我軍希望在滿足目標的同時使得總代價最小。偵查部門還發現,敵軍有一臺神秘機器。即使我軍切斷所有能源之后,他們也可以用那臺機器。機器產生的效果不僅僅會修復所有我軍炸毀的橋梁,而且會重新隨機資源分布(但可以保證的是,資源不會分布到1號島嶼上)。不過偵查部門還發現了這臺機器只能夠使用m次,所以我們只需要把每次任務完成即可。

Input

第一行一個整數n,代表島嶼數量。

接下來n-1行,每行三個整數u,v,w,代表u號島嶼和v號島嶼由一條代價為c的橋梁直接相連,保證1<=u,v<=n且1<=c<=100000。

第n+1行,一個整數m,代表敵方機器能使用的次數。

接下來m行,每行一個整數ki,代表第i次后,有ki個島嶼資源豐富,接下來k個整數h1,h2,…hk,表示資源豐富島嶼的編號。

Output

輸出有m行,分別代表每次任務的最小代價。

 

Sample Input

101 5 131 9 62 1 192 4 82 3 915 6 87 5 47 8 3110 7 932 10 64 5 7 8 33 9 4 6

Sample Output

123222

HINT

 對于100%的數據,2<=n<=250000,m>=1,sigma(ki)<=500000,1<=ki<=n-1

正解:虛樹+樹形dp。

閑得無聊學了下虛樹。虛樹就是說對于每個詢問有k個點,滿足sigma(k)為線性的問題,可以將每次詢問的點提出來新建一棵樹。對于k個結點,可以證明兩兩之間本質不同的lca最多只有k-1個。所以再把他們的lca全部加進去,再加一個公共的lca就行了(這道題是加1)。然后把這些結點按照dfs序從小到大排序,找出兩個相鄰點的lca。再將它們按照dfs序排序,開一個棧,如果棧頂元素是當前待加入結點的祖先,就連一條邊,否則彈出棧頂,然后把當前結點加入棧中。這樣,我們就能成功地建立一棵虛樹了。這題dp還是挺容易的,然而因為鄰接表清零出問題了然后調了半天。。

//It is made by wfj_2048~#include <algorithm>#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <vector>#include <cmath>#include <queue>#include <stack>#include <map>#include <set>#define inf (1e17)#define N (1000010)#define il inline#define RG  #define ll long long#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)using namespace std;struct edge{ int nt,to,dis; }g[N];int head[N],size[N],dfn[N],ed[N],dep[N],top[N],fa[N],son[N],a[N],st[N],vi[N],n,q,num,cnt;ll dis[N];il int gi(){    RG int x=0,q=1; RG char ch=getchar(); while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();    if (ch=='-') q=-1,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x;}il void insert(RG int from,RG int to,RG int dis){ g[++num]=(edge){head[from],to,dis},head[from]=num; return; }il int cmp(const int &a,const int &b){ return dfn[a]<dfn[b]; }il void dfs1(RG int x,RG int p){    dfn[x]=++cnt,dep[x]=dep[p]+1,fa[x]=p,size[x]=1; RG int v;    for (RG int i=head[x];i;i=g[i].nt){	v=g[i].to; if (v==p) continue;	dis[v]=min(dis[x],(ll)g[i].dis);	dfs1(v,x); size[x]+=size[v];	if (size[son[x]]<=size[v]) son[x]=v;    }    ed[x]=cnt; return;}il void dfs2(RG int x,RG int p,RG int a){    top[x]=a; if (son[x]) dfs2(son[x],x,a);    for (RG int i=head[x];i;i=g[i].nt){	RG int v=g[i].to;	if (v==p || v==son[x]) continue;	dfs2(v,x,v);    }    head[x]=0; return;}il int lca(RG int u,RG int v){    while (top[u]!=top[v]){	if (dep[top[u]]<dep[top[v]]) swap(u,v);	u=fa[top[u]];    }    return dep[u]<dep[v] ? u : v;}il ll dp(RG int x){    if (vi[x]) return dis[x]; RG ll res=0;    for (RG int i=head[x];i;i=g[i].nt) res+=dp(g[i].to);    return min(res,dis[x]);}il void work(){    n=gi(); RG int u,v,w; for (RG int i=1;i<n;++i) u=gi(),v=gi(),w=gi(),insert(u,v,w),insert(v,u,w);    dis[1]=inf,dfs1(1,0),dfs2(1,0,1); q=gi();    while(q--){	RG int k=gi(),M=k; for (RG int i=1;i<=k;++i) vi[a[i]=gi()]=1; sort(a+1,a+k+1,cmp);	for (RG int i=2;i<=k;++i) if (ed[a[i-1]]<dfn[a[i]]) a[++M]=lca(a[i-1],a[i]); a[++M]=1;	sort(a+1,a+M+1,cmp); M=unique(a+1,a+M+1)-a-1; RG int top=1; st[top]=a[1],num=0;	for (RG int i=2;i<=M;++i){	    while (top && ed[st[top]]<dfn[a[i]]) top--;	    insert(st[top],a[i],0),st[++top]=a[i];	}	PRintf("%lld/n",dp(1)); for (RG int i=1;i<=M;++i) vi[a[i]]=head[a[i]]=0;    }    return;}int main(){    File("war");    work();    return 0;}


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 东安县| 汝州市| 亳州市| 科技| 神池县| 上栗县| 寿光市| 潼关县| 宜兰市| 修武县| 巢湖市| 南漳县| 仁寿县| 措勤县| 特克斯县| 浮山县| 双城市| 贺兰县| 久治县| 石景山区| 台东县| 宁南县| 建湖县| 博乐市| 布尔津县| 高青县| 泸定县| 白沙| 丹凤县| 江华| 化德县| 基隆市| 托克逊县| 洛扎县| 海口市| 永修县| 嘉鱼县| 都兰县| 腾冲县| 甘孜| 贵定县|