PS國是一個擁有諸多城市的大國,國王Louis爲城市的交通建設可謂絞盡腦汁。Louis能夠在某些城市之間修建道路,在不一樣的城市之間修建道路須要不一樣的花費。Louis但願建造最少的道路使得國內全部的城市連通。可是因爲某些因素,城市之間修建道路須要的花費會隨着時間而改變,Louis會不斷獲得某道路的修建代價改變的消息,他但願每獲得一條消息後能當即知道使城市連通的最小花費總和, Louis決定求助於你來完成這個任務。html
文件第一行包含三個整數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)。ide
輸出包含Q行,第i行輸出得知前i條消息後使城市連通的最小花費總和。優化
【數據規模】 對於20%的數據, n≤1000,m≤6000,Q≤6000。 有20%的數據,n≤1000,m≤50000,Q≤8000,修改後的代價不會比以前的代價低。 對於100%的數據, n≤20000,m≤50000,Q≤50000。ui
(轉載請註明原文地址:http://www.cnblogs.com/LadyLex/p/8028462.html )spa
想法題……太神了
最暴力的固然是$O(n^{2}logn)$的暴力,可是這樣操做的次數就太多了,咱們須要優化
或者優化每次的邊數,或者優化操做的次數
優化操做次數顯然是不行的……
咱們會發現,有一些「絕對不可能成爲最優解」的邊在暴力裏被重複排序了
那麼咱們能夠直接把他們刪掉,來減小這種影響。
另外,有一些「絕對存在於最優解中「的邊,咱們預先計入他們的值,並在邊集中去除它們並縮點
這樣咱們就有了分治的思路,對」每一個修改操做控制的時間「分治3d
代碼打起來倒不是很長……
兩份代碼是兩種實現方法,第一份來自FoolMike神犇……是上面說的按時間分治,比較優秀
只有存在時間徹底覆蓋了l~r這個時間段的邊才存在,
而且有縮點和刪邊2個優化操做。
至於第二份……是本身打的,每次把這段時間內被修改的邊標記成+inf和-inf,+inf時沒被選上的邊是要刪去的,
-inf時被選上的邊是要必須選的。優化沒有打好,也就比暴力強一點……
這份代碼是給本身存着解悶的,想研究程序的請看第一份23333code
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\n",ans[i]); 88 }
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\n",ans[i]); 97 }