SDOI2011消耗战

Posted shxnb666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SDOI2011消耗战相关的知识,希望对你有一定的参考价值。

题面

https://www.luogu.org/problem/P2495

题解

#include<cstdio>
#include<algorithm>
#include<vector>
#include<stack>
#include<iostream>
using namespace std;
define ll long long
define N 250050;
vector<int> to[N],val[N];
int cnt,n;
int dfu,dfin[N],dfou[N],fa[N][25],dep[N];
ll mi[N];
inline void dfs(int x) 
  dfin[x]=++dfu;
  for(int i=1;i<=20;i++) fa[x][i]=fa[fa[x][i-1]][i-1];
  for(int i=to[x].size()-1;i>=0;i--) 
    int y=to[x][i];
    if (dfin[y]==0) 
      dep[y]=dep[x]+1; 
      if (mi[x]<val[x][i]) mi[y]=mi[x]; else mi[y]=val[x][i];
      fa[y][0]=x;
      dfs(y);
    
  
  dfou[x]=++dfu;


inline int lca(int u,int v) 
  if (dep[u]<dep[v]) swap(u,v);
  for (int i=20;i>=0;i--) if (dep[fa[u][i]]>=dep[v]) u=fa[u][i];
  if (u==v) return u;
  for (int i=20;i>=0;i--) if (fa[u][i]!=fa[v][i]) u=fa[u][i],v=fa[v][i];
  return fa[u][0];

int tr[4*N];
stack<int> s;
int m;
bool book[N];
ll sum[N];
inline bool cmp(int x,int y)
  int k1=(x>0)?dfin[x]:dfou[-x];
  int k2=(y>0)?dfin[y]:dfou[-y];
  return k1<k2;

int main()
  scanf("%d",&n);
  for (int i=1;i<n;i++) 
    int u,v,va;
    scanf("%d %d %d",&u,&v,&va);
    to[u].push_back(v); val[u].push_back(va);
    to[v].push_back(u); val[v].push_back(va);
  
  mi[1]=0x7f7f7f7f;
  fa[1][0]=1;
  dfs(1);
  scanf("%d",&m);
  for (int i=1;i<=m;i++) 
    int cot;
    scanf("%d",&cot);
    for (int j=1;j<=cot;j++) 
      scanf("%d",&tr[j]);
      book[tr[j]]=true; 
      sum[tr[j]]=mi[tr[j]];
    
    sort(tr+1,tr+cot+1,cmp);
    for (int j=1;j<cot;j++) 
      int lc=lca(tr[j],tr[j+1]);
      if (!book[lc]) tr[++cot]=lc,book[lc]=true;
    
    int nc=cot;
    for (int j=1;j<=nc;j++) tr[++cot]=-tr[j];
    if (!book[1]) tr[++cot]=1,tr[++cot]=-1;
    sort(tr+1,tr+cot+1,cmp);
    for (int j=1;j<=cot;j++) 
      if (tr[j]>0) s.push(tr[j]);
      else 
        int now=s.top(); s.pop();
        if (now!=1) 
          int fa=s.top();
          sum[fa]+=min(sum[now],mi[now]);
        
        else printf("%lld\n",sum[1]);
        sum[now]=0; book[now]=false;
      
    
  
  return 0;

 

以上是关于SDOI2011消耗战的主要内容,如果未能解决你的问题,请参考以下文章

[bzoj 2286]Sdoi2011消耗战

bzoj 2286: [Sdoi2011消耗战

BZOJ2286: [Sdoi2011]消耗战

[SDOI2011]消耗战

SDOI2011消耗战

AC日记——[SDOI2011]消耗战 洛谷 P2495