BZOJ2001 [Hnoi2010]City 城市建设


Solution

我们考虑一下这个东西怎么求解?

思考无果......

咦?

好像可以离线cdq,每一次判断一下如果这条边如果不选就直接删除,然后不确定的保留,必须选的就去确定连通性.

然后可以了?

好妙啊.cdq果然还是万金油.

代码实现

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<iostream>
using namespace std;
#define ll long long
#define re register
#define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
inline int gi()
{
    int f=1,sum=0;char ch=getchar();
    while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
    return f*sum;
}
const int N=100010,Inf=1e9+10;
struct node{
    int u,v,w,id;
    bool operator<(const node b)const{
        return w<b.w;
    }
}E[N],e[60][N],tmp[N],st[N];
int f[N],c[N],siz[50],W[N];
ll ans[N];
struct ques{
    int w,x;
}q[N];
int find(int x){
    if(x!=f[x])f[x]=find(f[x]);
    return f[x];
}
void init(int z){
    for(int i=1;i<=z;i++)f[tmp[i].u]=tmp[i].u;
    for(int i=1;i<=z;i++)f[tmp[i].v]=tmp[i].v;
}
void Solve1(int &z,ll &Ans){
    init(z);sort(tmp+1,tmp+z+1);int top=0;
    for(int i=1;i<=z;i++)
        if(find(tmp[i].u)!=find(tmp[i].v)){
            f[find(tmp[i].u)]=find(tmp[i].v);
            st[++top]=tmp[i];
        }
    for(int i=1;i<=top;i++)f[st[i].u]=st[i].u,f[st[i].v]=st[i].v;
    for(int i=1;i<=top;i++)
        if(st[i].w>-Inf){
            f[find(st[i].u)]=find(st[i].v);
            Ans+=st[i].w;
        }
    top=0;
    for(int i=1;i<=z;i++)
        if(find(tmp[i].u)!=find(tmp[i].v)){
            st[++top]=tmp[i];
            c[tmp[i].id]=top;
            st[top].u=find(tmp[i].u);
            st[top].v=find(tmp[i].v);
        }
    z=top;for(int i=1;i<=top;i++)tmp[i]=st[i];
}
void Solve2(int &z)
{
    init(z);sort(&tmp[1],&tmp[z+1]);int top=0;
    for(int i=1;i<=z;++i)
        if(find(tmp[i].u)!=find(tmp[i].v))
            f[find(tmp[i].u)]=find(tmp[i].v),st[++top]=tmp[i],c[tmp[i].id]=top;
        else if(tmp[i].w>=Inf)st[++top]=tmp[i],c[tmp[i].id]=top;
    z=top;for(int i=1;i<=top;++i)tmp[i]=st[i];
}
void cdq(int l,int r,int dep,ll Ans){
    if(l==r)W[q[l].x]=q[l].w;
    int z=siz[dep],mid=(l+r)>>1;
    for(int i=1;i<=z;i++)e[dep][i].w=W[e[dep][i].id];
    for(int i=1;i<=z;i++)tmp[i]=e[dep][i],c[tmp[i].id]=i;
    if(l==r){
        init(z);sort(tmp+1,tmp+z+1);
        for(int i=1;i<=z;i++)
            if(find(tmp[i].u)!=find(tmp[i].v)){
                f[find(tmp[i].u)]=find(tmp[i].v);Ans+=tmp[i].w;
            }
        ans[l]=Ans;return;
    }
    for(int i=l;i<=r;i++)tmp[c[q[i].x]].w=-Inf;
    Solve1(z,Ans);
    for(int i=l;i<=r;i++)tmp[c[q[i].x]].w=+Inf;
    Solve2(z);
    for(int i=1;i<=z;i++)e[dep+1][i]=tmp[i];siz[dep+1]=z;
    cdq(l,mid,dep+1,Ans);cdq(mid+1,r,dep+1,Ans);
}
int main()
{
    int n,m,Q;
    n=gi();m=gi();Q=gi();
    for(int i=1;i<=m;i++)E[i].u=gi(),E[i].v=gi(),E[i].w=gi(),E[i].id=i;
    for(int i=1;i<=Q;i++)q[i].x=gi(),q[i].w=gi();
    for(int i=1;i<=m;i++)W[i]=E[i].w;
    for(int i=1;i<=m;i++)e[0][i]=E[i];
    siz[0]=m;cdq(1,Q,0,0);
    for(int i=1;i<=Q;i++)printf("%lld\n",ans[i]);
    return 0;
}

【BZOJ2001】 [Hnoi2010]City 城市建设的更多相关文章

  1. BZOJ2001 [Hnoi2010]City 城市建设 CDQ分治

    2001: [Hnoi2010]City 城市建设 Time Limit: 20 Sec  Memory Limit: 162 MB Description PS国是一个拥有诸多城市的大国,国王Lou ...

  2. BZOJ2001 [Hnoi2010]City 城市建设 【CDQ分治 + kruskal】

    题目链接 BZOJ2001 题解 CDQ分治神题... 难想难写.. 比较朴素的思想是对于每个询问都求一遍\(BST\),这样做显然会爆 考虑一下时间都浪费在了什么地方 我们每次求\(BST\)实际上 ...

  3. BZOJ2001: [Hnoi2010]City 城市建设

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2001 cdq分治+重建图. 可以保留当前一定会被选的非修改边然后把点缩起来.这样的话每次点数至 ...

  4. BZOJ 2001: [Hnoi2010]City 城市建设

    2001: [Hnoi2010]City 城市建设 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 1132  Solved: 555[Submit][ ...

  5. 【bzoj2001】 Hnoi2010—City 城市建设

    http://www.lydsy.com/JudgeOnline/problem.php?id=2001 (题目链接) 题意 给出一张无向图,$m$组操作,每次修改一条边的权值,对于每次操作输出修改之 ...

  6. 2001: [Hnoi2010]City 城市建设 - BZOJ

    DescriptionPS国是一个拥有诸多城市的大国,国王Louis为城市的交通建设可谓绞尽脑汁.Louis可以在某些城市之间修建道路,在不同的城市之间修建道路需要不同的花费.Louis希望建造最少的 ...

  7. 【刷题】BZOJ 2001 [Hnoi2010]City 城市建设

    Description PS国是一个拥有诸多城市的大国,国王Louis为城市的交通建设可谓绞尽脑汁.Louis可以在某些城市之间修建道路,在不同的城市之间修建道路需要不同的花费.Louis希望建造最少 ...

  8. [HNOI2010]CITY 城市建设

    问题: 给一张图,支持边长度修改,求MST 题解: 自己想就想不到了.. 考虑cdq分治 1.首先求出一定有用的边 对于未处理的边,全部设为-INF,求一次MST,出现在MST上的边一定最终出现在后面 ...

  9. 【HNOI2010】城市建设(对时间分治 & Kruskal)

    Description \(n\) 个点 \(m\) 条边的带边权无向图.\(q\) 次操作,每次修改一条边的权值. 求每次修改后的最小生成树的边权和. Hint \(1\le n\le 2\time ...

随机推荐

  1. 【转】VxWorks中高精度实时时钟的实现及C语言汇编混合编程

    最近一个项目中需要在VxWorks下使用一个高精度实时时钟,要求精度为1ms,溢 出时间大于5小时.VxWorks提供系统时钟,该时钟在操作系统启动后开始计数,精度为1个tick,可以通过tickGe ...

  2. 【Game】2048小游戏

    每个男孩都有一个游戏梦吧,本例简单讲述一款很火的游戏<2048>的制作. 本例参考地址:https://www.imooc.com/learn/76 游戏准备 1.游戏的逻辑(2048大家 ...

  3. kbmmw 中JSON 中使用SQL 查询

    前面讲到了kbmmw 的JSON 对象操作,如何快速的查找JSON 中的值? 一种办法就是通过遍历的方法,其实在kbmmw 还有一种灵活的查询方式, 就是通过SQL 方式查询JSON 中的值.也就是说 ...

  4. De Bruijn序列

    最近文章中经常出现及De Bruijin 这个关键字,网上搜索了一下,记录下来. De Bruijn序列 (德布鲁因序列) 问题:能否构造一个长度为2的n次方的二进制环状串,使得二进制环状串中总共2的 ...

  5. 2018.11.07 NOIP模拟 数独(模拟)

    传送门 sbsbsb签到题. 读题时间比写题时间长系列. 写一个checkcheckcheck函数来检验当前时间段第(i,j)(i,j)(i,j)号格子能否放入kkk就行了. 代码

  6. yml的mybatis的sql查看;Mybatis+Springboot 控制台查看日志,Mybatis结合springboot打印日志

    1.配置如图 文件为yml mybatis: mapper-locations: classpath:com/springboot/transaction/mapper/*.xml configura ...

  7. BitMap的简单实现

    面试结束的这些日子好几次接触到BitMap这个东西.到底是啥呢,究其原因就是虽然它的使用条件较为苛刻,但是它对应的时间复杂度和空间复杂度真的是惊人的好. 首先是根据其思想先写了一个比较差的实现代码: ...

  8. Java8函数式接口/Lambda表达式/接口默认方法/接口静态方法/接口冲突方法重写/lambda表达式指定泛型类型等

    一:函数式接口 1.函数式接口的概念就是此接口必须有且只能有一个抽象方法,可以通过@FunctionalInterface来显示规定(类似@Override),但是没有此注解的但是只有一个抽象方法的接 ...

  9. html5 ajax多图片可预览上传图片

    最近不是特别忙,我就利用html5写了个上传图片(或其他文件)的页面,主要利用是html5的file api,此页面比较简陋,没做样式的优化,包含上传图片预览,多图片上传,上传进度条(利用html5的 ...

  10. 1.4isAlive()方法

    方法isAlive()的功能是判断当前线程是否处于活动状态 活动状态是线程已经启动且尚未终止,线程处于正在运行或准备开始运行的状态,就认为线程是存活的. 测试如下 package com.cky.th ...