zoukankan      html  css  js  c++  java
  • BZOJ2001 [Hnoi2010]City 城市建设 CDQ分治

    2001: [Hnoi2010]City 城市建设

    Time Limit: 20 Sec  Memory Limit: 162 MB

    Description

    PS国是一个拥有诸多城市的大国,国王Louis为城市的交通建设可谓绞尽脑汁。Louis可以在某些城市之间修建道路,在不同的城市之间修建道路需要不同的花费。Louis希望建造最少的道路使得国内所有的城市连通。但是由于某些因素,城市之间修建道路需要的花费会随着时间而改变,Louis会不断得到某道路的修建代价改变的消息,他希望每得到一条消息后能立即知道使城市连通的最小花费总和, Louis决定求助于你来完成这个任务。

    Input

    文件第一行包含三个整数N,M,Q,分别表示城市的数目,可以修建的道路个数,及收到的消息个数。 接下来M行,第i+1行有三个用空格隔开的整数Xi,Yi,Zi(1≤Xi,Yi≤n, 0≤Zi≤50000000),表示在城市Xi与城市Yi之间修建道路的代价为Zi。接下来Q行,每行包含两个数k,d,表示输入的第k个道路的修建代价修改为d(即将Zk修改为d)。

    Output

    输出包含Q行,第i行输出得知前i条消息后使城市连通的最小花费总和。

    Sample Input

    5 5 3
    1 2 1
    2 3 2
    3 4 3
    4 5 4
    5 1 5
    1 6
    1 1
    5 3

    Sample Output

    14
    10
    9

    HINT

    【数据规模】 对于20%的数据, n≤1000,m≤6000,Q≤6000。 有20%的数据,n≤1000,m≤50000,Q≤8000,修改后的代价不会比之前的代价低。 对于100%的数据, n≤20000,m≤50000,Q≤50000。

    (转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/8028462.html )

    想法题……太神了
    最暴力的当然是$O(n^{2}logn)$的暴力,但是这样操作的次数就太多了,我们需要优化
    或者优化每次的边数,或者优化操作的次数
    优化操作次数显然是不行的……
    我们会发现,有一些“绝对不可能成为最优解”的边在暴力里被重复排序了
    那么我们可以直接把他们删掉,来减少这种影响。
    另外,有一些“绝对存在于最优解中“的边,我们预先计入他们的值,并在边集中去除它们并缩点
    这样我们就有了分治的思路,对”每个修改操作控制的时间“分治

    代码打起来倒不是很长……
    两份代码是两种实现方法,第一份来自FoolMike神犇……是上面说的按时间分治,比较优秀
    只有存在时间完全覆盖了l~r这个时间段的边才存在,
    并且有缩点和删边2个优化操作。
    至于第二份……是自己打的,每次把这段时间内被修改的边标记成+inf和-inf,+inf时没被选上的边是要删去的,
    -inf时被选上的边是要必须选的。优化没有打好,也就比暴力强一点……
    这份代码是给自己存着解闷的,想研究程序的请看第一份23333

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <vector>
     5 using namespace std;
     6 #define inf 50000001
     7 #define N 20010
     8 #define M 50010
     9 #define LL long long
    10 char B[1<<15],*cS=B,*cT=B;
    11 #define getc (cS==cT&&(cT=(cS=B)+fread(B,1,1<<15,stdin),cS==cT)?0:*cS++)
    12 inline int read()
    13 {
    14     int x=0;register char c=getc;
    15     while(c<'0'||c>'9')c=getc;
    16     while(c>='0'&&c<='9')x=10*x+(c^48),c=getc;
    17     return x;
    18 }
    19 int n,m,q;
    20 struct edge{int st,ed,val,L,R;}s[M];
    21 vector<edge>E;
    22 struct Gragh
    23 {
    24     int fa[N];
    25     inline int find(int a){return fa[a]==a?a:fa[a]=find(fa[a]);}
    26     inline void intn(int sz){for(int i=1;i<=sz;++i)fa[i]=i;}
    27 }S;
    28 inline bool mt(const edge &a,const edge &b){return a.val<b.val;}
    29 LL ans[M];
    30 int sta[M<<1],stb[M<<1],stc[M<<1];
    31 int id[N];
    32 inline void CDQ(int l,int r,int size,vector<edge> Ex)
    33 {
    34     vector<edge> tmp;
    35     int i,sz,x,y,cnt,mi=l+r>>1;edge z;
    36     for(i=0,sz=Ex.size();i<sz;++i)
    37         if(l<=Ex[i].R&&Ex[i].L<=r)tmp.push_back(Ex[i]);
    38     sort(tmp.begin(),tmp.end(),mt);
    39     S.intn(size);LL temp=0;
    40     for(i=0,sz=tmp.size();i<sz;++i)
    41     {
    42         z=tmp[i],stc[i]=(z.L<=l&&r<=z.R),
    43         sta[i]=stb[i]=0,x=S.find(z.st),y=S.find(z.ed);
    44         if(x!=y)
    45         {
    46             S.fa[x]=y;
    47             if(stc[i])temp+=z.val,sta[i]=1;
    48         }
    49     }
    50     for(i=l;i<=r;++i)ans[i]+=temp;
    51     if(l==r)return;
    52     S.intn(size);
    53     for(i=0,sz=tmp.size();i<sz;++i)
    54     {
    55         z=tmp[i],x=S.find(z.st),y=S.find(z.ed);
    56         if(x==y)stb[i]=1;
    57         else if(stc[i])S.fa[x]=y;
    58     }
    59     S.intn(size);
    60     for(i=0,sz=tmp.size();i<sz;++i)
    61         if(sta[i]){z=tmp[i],S.fa[S.find(z.st)]=S.find(z.ed);}
    62     for(cnt=0,i=1;i<=size;++i)
    63         if(S.find(i)==i)id[i]=++cnt;
    64     Ex.clear();
    65     for(i=0,sz=tmp.size();i<sz;++i)
    66         if(!sta[i]&&!stb[i])
    67             tmp[i].st=id[S.find(tmp[i].st)],
    68             tmp[i].ed=id[S.find(tmp[i].ed)],
    69             Ex.push_back(tmp[i]);
    70     CDQ(l,mi,cnt,Ex);
    71     CDQ(mi+1,r,cnt,Ex);
    72 }
    73 int last[M];
    74 int main()
    75 {
    76     register int i,j,x,y;edge z;
    77     n=read(),m=read(),q=read();
    78     for(i=1;i<=m;++i)
    79         s[i].st=read(),s[i].ed=read(),s[i].val=read();
    80     for(i=1;i<=q;++i)
    81         x=read(),y=read(),z=s[x],z.L=last[x],z.R=i-1,
    82         E.push_back(z),s[x].val=y,last[x]=i;
    83     for(i=1;i<=m;++i)
    84         s[i].L=last[i],s[i].R=q,E.push_back(s[i]);
    85     CDQ(1,q,n,E);
    86     for(i=1;i<=q;++i)
    87         printf("%lld
    ",ans[i]);
    88 }
    能AC的程序
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <vector>
     5 using namespace std;
     6 #define inf 50000001
     7 #define N 20010
     8 #define M 50010
     9 #define LL long long
    10 char B[1<<15],*S=B,*T=B;
    11 #define getc (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?0:*S++)
    12 inline int read()
    13 {
    14     int x=0;register char c=getc;
    15     while(c<'0'||c>'9')c=getc;
    16     while(c>='0'&&c<='9')x=10*x+(c^48),c=getc;
    17     return x;
    18 }
    19 int n,m,q,top,sta[M],stb[M],topa;
    20 int st[M],ed[M],val[M];
    21 int changeid[M],changeval[M],mem[M];
    22 inline bool mt(const int &a,const int &b){return val[a]<val[b];}
    23 struct Gragh
    24 {
    25     int fa[N];int already;
    26     vector<int>edge;
    27     inline void operator = (const Gragh &b)
    28         {memcpy(fa,b.fa,sizeof(fa)),edge=b.edge,already=b.already;}
    29     inline int find(int a)
    30         {return fa[a]==a?a:fa[a]=find(fa[a]);}
    31 }G[20];
    32 LL ans[M];
    33 inline void CDQ(int l,int r,int layer)
    34 {
    35     vector<int>::iterator it;
    36     int i,sz,x,y,mi=l+r>>1;
    37     if(l==r)
    38     {
    39         val[changeid[l]]=changeval[l];
    40         sort(G[layer].edge.begin(),G[layer].edge.end(),mt);
    41         for(it=G[layer].edge.begin();G[layer].already<n-1&&it!=G[layer].edge.end();++it)
    42         {
    43             x=G[layer].find(st[*it]),y=G[layer].find(ed[*it]);
    44             if(x!=y)++G[layer].already,G[layer].fa[x]=y,ans[l]+=val[*it];
    45         }
    46         return;
    47     }
    48     for(int i=l;i<=r;++i)mem[changeid[i]]=val[changeid[i]];
    49     for(int i=l;i<=r;++i)val[changeid[i]]=-inf;
    50     sort(G[layer].edge.begin(),G[layer].edge.end(),mt);
    51     LL temp=0;sz=0;topa=0;
    52     for(it=G[layer].edge.begin();sz!=n-1&&G[layer].already!=n-1&&it!=G[layer].edge.end();++it)
    53     {
    54         x=G[layer].find(st[*it]),y=G[layer].find(ed[*it]);
    55         if(x!=y)
    56         {
    57             ++sz,G[layer].fa[x]=y;
    58             if(val[*it]!=-inf)sta[++topa]=*it,temp+=val[*it],++G[layer].already;
    59         }
    60     }
    61     for(x=l;x<=r;++x)ans[x]+=temp;
    62     G[layer]=G[layer-1];
    63     for(int i=l;i<=r;++i)val[changeid[i]]=inf;
    64     sort(G[layer].edge.begin(),G[layer].edge.end(),mt);
    65     memset(stb,0,sizeof(stb));
    66     for(sz=0,it=G[layer].edge.begin();sz!=n-1&&it!=G[layer].edge.end();++it)
    67     {
    68         x=G[layer].find(st[*it]),y=G[layer].find(ed[*it]);
    69         if(x!=y)++sz,G[layer].fa[x]=y;
    70         else if(val[*it]!=inf)stb[*it]=1;
    71     }
    72     for(;it!=G[layer].edge.end();++it)
    73         if(val[*it]!=inf)stb[*it]=1;
    74     G[layer]=G[layer-1];
    75     for(i=1;i<=topa;++i)
    76         x=G[layer].find(st[sta[i]]),y=G[layer].find(ed[sta[i]]),G[layer].fa[x]=y;
    77     for(i=0,sz=G[layer].edge.size();i<sz;++i)
    78         if(stb[ G[layer].edge[i] ])
    79             G[layer].edge[i]=G[layer].edge[sz-1],--sz,--i,G[layer].edge.pop_back();
    80     for(int i=l;i<=r;++i)val[changeid[i]]=mem[changeid[i]];
    81     G[layer+1]=G[layer],CDQ(l,mi,layer+1);
    82     G[layer+1]=G[layer],CDQ(mi+1,r,layer+1);
    83 }
    84 int main()
    85 {
    86     register int i,j;n=read(),m=read(),q=read();
    87     for(i=1;i<=m;++i)
    88         st[i]=read(),ed[i]=read(),val[i]=read(),
    89         G[0].edge.push_back(i),G[1].edge.push_back(i);
    90     for(i=1;i<=n;++i)G[0].fa[i]=G[1].fa[i]=i;
    91     G[0].already=G[1].already=0;
    92     for(i=1;i<=q;++i)
    93         changeid[i]=read(),changeval[i]=read();
    94     CDQ(1,q,1);
    95     for(i=1;i<=q;++i)
    96         printf("%lld
    ",ans[i]);
    97 }
    TLE的程序
  • 相关阅读:
    Linux getcwd()的实现【转】
    关于__GNU_SOURCE 这个宏---如何开启【转】
    UBI 文件系统移植 sys 设备信息【转】
    Linux USB驱动框架分析【转】
    局部变量、全局变量、堆、堆栈、静态和全局【转】
    C语言字节对齐问题详解【转】
    usb驱动的基本结构和函数简介【转】
    makefile函数集锦【转】
    非常好!!!Linux源代码阅读——内核引导【转】
    JQuery日记6.9 Promise/A之Callbacks
  • 原文地址:https://www.cnblogs.com/LadyLex/p/8028462.html
Copyright © 2011-2022 走看看