bzoj 2286: [Sdoi2011]消耗战

来源:互联网 发布:js怎么调用类库 编辑:程序博客网 时间:2024/05/14 09:04

题目大意,切掉若干条边,使根不能到指定的点,代价最小,多次询问。

这篇东西不错:点击打开链接

虚树的模板题,注意卡时,在建虚树前先将一条链的点删剩一个,每个点记录到根最短的边边权。

貌似数据有误?反正我开了long long 记录边权就A了。

LCA模板一定不能错啊啊啊啊!

code:

#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>#define LL long longusing namespace std;const LL inf=(1LL<<56);struct trnode{int dep,fa[25];}tr[250010];int ys[250010],z=0;LL C[250010];LL f[250010];struct node{int y,next;LL c;}a[500010];int last[250010],len;int n,h[250010],num;int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}int LLread(){    LL x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}void ins(int x,int y,LL c){a[++len].y=y;a[len].c=c;a[len].next=last[x];last[x]=len;}void dfs(int x,int fa,LL c){ys[x]=++z;tr[x].fa[0]=fa;tr[x].dep=tr[fa].dep+1;C[x]=c;for(int i=1;(1<<i)<=tr[x].dep;i++)tr[x].fa[i]=tr[tr[x].fa[i-1]].fa[i-1];for(int i=last[x];i;i=a[i].next){int y=a[i].y;if(y!=fa) dfs(y,x,min(a[i].c,c));}}int findlca(int x,int y){if(tr[x].dep<tr[y].dep) swap(x,y);for(int i=19;i>=0;i--)if((1<<i)<=tr[x].dep-tr[y].dep) x=tr[x].fa[i];if(x==y) return x;for(int i=19;i>=0;i--)if((1<<i)<=tr[x].dep&&tr[x].fa[i]!=tr[y].fa[i])x=tr[x].fa[i],y=tr[y].fa[i];return tr[x].fa[0];}bool cmp(int a,int b){return ys[a]<ys[b];}int sta[250010],top;void dfs(int x){f[x]=(LL)C[x];LL s=0;for(int i=last[x];i;i=a[i].next){int y=a[i].y;dfs(y);s+=f[y];}if(last[x]) f[x]=min(f[x],s);last[x]=0;}void build(){top=0;sort(h+1,h+num+1,cmp);sta[++top]=1;int tot=num;num=1;for(int i=2;i<=tot;i++){int lca=findlca(h[num],h[i]);if(lca!=h[num]) h[++num]=h[i];}len=0;for(int i=1;i<=num;i++){int x=h[i],lca=findlca(sta[top],x);if(lca==sta[top]) sta[++top]=x;else{while(top>=2&&tr[sta[top-1]].dep>=tr[lca].dep){ins(sta[top-1],sta[top],1LL);top--;}if(lca!=sta[top]){ins(lca,sta[top],1LL);sta[top]=lca;}sta[++top]=x;}}for(int i=1;i<top;i++) ins(sta[i],sta[i+1],1);dfs(1);printf("%lld\n",f[1]);}int main(){n=read();memset(last,0,sizeof(last));len=0;for(int i=1;i<n;i++){int x,y,c;x=read();y=read();c=LLread();ins(x,y,c);ins(y,x,c);}tr[0].dep=-1;dfs(1,0,inf);int T;T=read();memset(last,0,sizeof(last));while(T--){num=read();for(int i=1;i<=num;i++) h[i]=read();build();}}


原创粉丝点击