码迷,mamicode.com
首页 > 其他好文 > 详细

【SDOI2011】消耗战

时间:2019-08-29 00:27:42      阅读:134      评论:0      收藏:0      [点我收藏+]

标签:int   str   ++   http   stack   scan   clu   min   i++   

题面

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】消耗战

标签:int   str   ++   http   stack   scan   clu   min   i++   

原文地址:https://www.cnblogs.com/shxnb666/p/11427287.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!