当前位置: 首页 > news >正文

一本通1554【例 3】异象石

1554:【例 3】异象石

时间限制: 1000 ms         内存限制: 524288 KB

题目描述

原题来自:Contest Hunter Round #56

在 Adera 的异时空中有一张地图。这张地图上有 N 个点,有 N1 条双向边把它们连通起来。起初地图上没有任何异象石,在接下来的 M 个时刻中,每个时刻会发生以下三种类型的事件之一:

  1. 地图的某个点上出现了异象石(已经出现的不会再次出现);
  2. 地图某个点上的异象石被摧毁(不会摧毁没有异象石的点);
  3. 向玩家询问使所有异象石所在的点连通的边集的总长度最小是多少。

请你作为玩家回答这些问题。下图是一个例子,灰色节点表示出现了异象石,加粗的边表示被选为连通异象石的边集。

stone.png

输入格式

第一行有一个整数 N,表示点的个数;

接下来 N1 行每行三个整数 x,y,z,表示点 x 和 y 之间有一条长度为 z 的双向边;

第 N+1 行有一个正整数 M;

接下来 M 行每行是一个事件,事件是以下三种格式之一:

  • + x:表示点 x 上出现了异象石;
  • - x:表示点 x 上的异象石被摧毁;
  • ?:表示询问使当前所有异象石所在的点连通所需的边集的总长度最小是多少。

输出格式

对于每个 ? 事件,输出一个整数表示答案。

样例

样例输入

6 
1 2 1 
1 3 5 
4 1 7 
4 5 3 
6 4 2 
10 
+ 3 
+ 1 
? 
+ 6 
? 
+ 5 
? 
- 6 
- 3 
?

样例输出

5 
14 
17 
10

数据范围与提示

对于 30% 的数据,1n,m10^3;

对于另 20% 的数据,地图是一条链,或者一朵菊花;

对于 100% 的数据,1n,m10^5,1x,yn,x !=y,1z10^9。

 

sol:先考虑下给你一堆点怎么求把他们全部连起来需要的费用,发现就是从一个点以任意顺序依次遍历每个点再回到出发点的边权和的1/2,之后就会容易一点,假定这是以dfs遍历的,弄一个set,加点删点是对应的加上几条路径或减去几条就可以了

#include <bits/stdc++.h>
using namespace std;
const int N=100005,M=200005,inf=0x3f3f3f3f;
int n,m;
struct Tree
{
    int tot,Next[M],to[M],val[M],head[N];
    inline void add(int x,int y,int z)
    {
        Next[++tot]=head[x];
        to[tot]=y;
        val[tot]=z;
        head[x]=tot;
        return;
    }
    int Id_cnt,Id[N],Xuhao[N]; //dfs序
    bool Inset[N];
    int Depth[N],F[N][23];
    long long Dis[N];
    inline void dfs(int x,int fa)
    {
        Id[++Id_cnt]=x; Xuhao[x]=Id_cnt;
        F[x][0]=fa; Depth[x]=Depth[fa]+1;
        int i;
        for(i=head[x];i;i=Next[i]) if(to[i]!=fa)
        {
            Dis[to[i]]=Dis[x]+val[i];
            dfs(to[i],x);
        }
        return;
    }
    set<int>Set;
    inline void Pre()
    {
        int i,j;
        dfs(1,0);
        for(i=1;i<=19;i++)
        {
            for(j=1;j<=n;j++) F[j][i]=F[F[j][i-1]][i-1];
        }
        Set.insert(-inf); Set.insert(inf);
        return;
    }
    inline int Ask_Lca(int x,int y)
    {
        int i;
        if(Depth[x]<Depth[y]) swap(x,y);
        for(i=19;~i;i--) if(Depth[F[x][i]]>=Depth[y])
        {
            x=F[x][i];
        }
        if(x==y) return x;
        for(i=19;~i;i--) if(F[x][i]!=F[y][i])
        {
            x=F[x][i]; y=F[y][i];
        }
        return F[x][0];
    }
    inline long long Ask_Dis(int x,int y)
    {
        return Dis[x]+Dis[y]-(Dis[Ask_Lca(x,y)]<<1);
    }
    long long Dis_All;
    inline void Point_Add(int x)
    {
        if(Inset[Xuhao[x]]) return;
        Set.insert(Xuhao[x]); Inset[Xuhao[x]]=1;
        set<int>::iterator it=Set.upper_bound(Xuhao[x]);
        int p2=(*it),p1=(*(--(--it)));
//        printf("%d %d\n",p1,p2);
//        puts("EEE");
        if(p1!=-inf) Dis_All+=Ask_Dis(Id[p1],x);
        if(p2!=inf) Dis_All+=Ask_Dis(x,Id[p2]);
//        puts("FFF");
        if((p1!=-inf)&&(p2!=inf)) Dis_All-=Ask_Dis(Id[p1],Id[p2]);
        return;
    }
    inline void Point_Del(int x)
    {
        if(!Inset[Xuhao[x]]) return;
        Set.erase(Xuhao[x]); Inset[Xuhao[x]]=0;
        set<int>::iterator it=Set.upper_bound(Xuhao[x]);
        int p2=(*it),p1=(*(--it));
        if(p1!=-inf) Dis_All-=Ask_Dis(Id[p1],x);
        if(p2!=inf) Dis_All-=Ask_Dis(x,Id[p2]);
        if((p1!=-inf)&&(p2!=inf)) Dis_All+=Ask_Dis(Id[p1],Id[p2]);
        return;
    }
    inline long long Get_ans()
    {
        long long DD=(Set.size()>3)?(Ask_Dis(Id[*(Set.upper_bound(-inf))],Id[*(--Set.lower_bound(inf))])):0;
        return (Dis_All+DD)>>1;
    }
    inline void Init()
    {
        tot=Dis_All=Id_cnt=0;
        memset(head,0,sizeof head);
        memset(Inset,0,sizeof Inset);
        return;
    }
}T;
int main()
{
//    freopen("stone6.in","r",stdin);
//    freopen("my.out","w",stdout);
    int i;
    scanf("%d",&n);
    for(i=1;i<n;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        T.add(x,y,z); T.add(y,x,z);
    }
    T.Pre();
    scanf("%d",&m);
    for(i=1;i<=m;i++)
    {
        char Ch[5];
        int x;
        scanf("%s",Ch+1);
        switch (Ch[1])
        {
            case '+':
                scanf("%d",&x);
                T.Point_Add(x);
                break;
            case '-':
                scanf("%d",&x);
                T.Point_Del(x);
                break;
            case '?':
                printf("%lld\n",T.Get_ans());
                break;
            default:
                break;
        }
    }
    return 0;
}
/*
input
6 
1 2 1 
1 3 5 
4 1 7 
4 5 3 
6 4 2 
10 
+ 3 
+ 1 
? 
+ 6 
? 
+ 5 
? 
- 6 
- 3 
?
output
5 
14 
17 
10
*/
View Code

 

转载于:https://www.cnblogs.com/gaojunonly1/p/10352761.html

相关文章:

  • codeforces 140E.New Year Garland
  • 加密_散乱的密文
  • 力扣——二叉搜索树中的搜索
  • visualsvn for vs2017 初始化错误
  • 寒假开学回忆
  • 4算法与数据结构
  • C++虚继承
  • L3-009 长城 (30 分)
  • 股票
  • 如何创建一个Asp .Net Web Api项目
  • RAID LVM ISCSI
  • 在采用vue-cli Post Get
  • Linux的常识
  • P1606 [USACO07FEB]白银莲花池Lilypad Pond
  • Galera Cluster——一种新型的高一致性MySQL集群架构
  • 【译】理解JavaScript:new 关键字
  • 【知识碎片】第三方登录弹窗效果
  • canvas实际项目操作,包含:线条,圆形,扇形,图片绘制,图片圆角遮罩,矩形,弧形文字...
  • Consul Config 使用Git做版本控制的实现
  • Docker: 容器互访的三种方式
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • JavaScript 无符号位移运算符 三个大于号 的使用方法
  • k8s如何管理Pod
  • Meteor的表单提交:Form
  • PAT A1120
  • RxJS 实现摩斯密码(Morse) 【内附脑图】
  • Solarized Scheme
  • spring security oauth2 password授权模式
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比...
  • 从0到1:PostCSS 插件开发最佳实践
  • 动态规划入门(以爬楼梯为例)
  • 分布式事物理论与实践
  • 前端之React实战:创建跨平台的项目架构
  • 线上 python http server profile 实践
  • 京东物流联手山西图灵打造智能供应链,让阅读更有趣 ...
  • 正则表达式-基础知识Review
  • ​Distil-Whisper:比Whisper快6倍,体积小50%的语音识别模型
  • #if 1...#endif
  • (day 12)JavaScript学习笔记(数组3)
  • (二)Eureka服务搭建,服务注册,服务发现
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (四)TensorRT | 基于 GPU 端的 Python 推理
  • (一)UDP基本编程步骤
  • ******IT公司面试题汇总+优秀技术博客汇总
  • .NET Core MongoDB数据仓储和工作单元模式封装
  • .net framework4与其client profile版本的区别
  • .net 设置默认首页
  • .net/c# memcached 获取所有缓存键(keys)
  • .NET中winform传递参数至Url并获得返回值或文件
  • .vue文件怎么使用_我在项目中是这样配置Vue的
  • [Angular 基础] - 指令(directives)
  • [Ariticle] 厚黑之道 一 小狐狸听故事
  • [C++]——带你学习类和对象
  • [CareerCup] 14.5 Object Reflection 对象反射
  • [ERROR] Plugin 'InnoDB' init function returned error