BZOJ2238 Mst [+ minimum spanning tree sectional segment tree +]

Run again mst. For an edge on non-mst, apparently it does not affect deleted.

If you remove the tree edge, this time corresponding to the remaining two blocks communication. Mst may prove to be reconstituted only need to add a minimum two connected communication block edges, will not permit, yy bit, because right edge of the original communication block and even has been minimized, and do not move, if you switch to two over the edge, certainly not better.

So the question is cut off side of the tree, looking for the smallest Unicom side. You may LCT . `` `` `

This tree snapped title Unicom find a common side of the idea, to make China Unicom, have to have a non-chain side of the tree through the end points of the broken edge is formed. In other words, a non-chain side of the tree two trees may be formed after the broken link tree if and only if he side edges broken through.

This idea should be previously poj this topic "Yami no chain" appeared, it is easy card.

So just look through the smallest of all non-tree edge off the side of which, to use his Unicom, on the whole, it is to update the wave with their minimum price on each non-tree edge path.

With tree line marking maintenance, when the last search query directly calculate the answer to a single point minimum.

Note sentenced to no solution.

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<cmath>
  6 #define dbg(x) cerr << #x << " = " << x <<endl
  7 using namespace std;
  8 typedef long long ll;
  9 typedef double db;
 10 typedef pair<int,int> pii;
 11 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
 12 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
 13 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;}
 14 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;}
 15 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
 16 template<typename T>inline T read(T&x){
 17     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
 18     while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
 19 }
 20 const int N=1e5+7,INF=0x3f3f3f3f;
 21 struct thxorz{int to,nxt,w;}G[N];
 22 int Head[N],tot,used[N];
 23 int n,m,q;
 24 inline void Addedge(int x,int y,int z){
 25     G[++tot].to=y,G[tot].nxt=Head[x],Head[x]=tot,G[tot].w=z;
 26     G[++tot].to=x,G[tot].nxt=Head[y],Head[y]=tot,G[tot].w=z;
 27 }
 28 struct stothx{
 29     int u,v,w,id;
 30     inline bool operator <(const stothx&x)const{return w<x.w;}
 31 }E[N],_E[N];
 32 int anc[N],ans;
 33 int get_anc(int x){return x==anc[x]?x:anc[x]=get_anc(anc[x]);}
 34 int fa[N],topfa[N],son[N],cnt[N],d[N],st[N],tim;
 35 #define y G[j].to
 36 void dfs1(int x,int f){
 37     fa[x]=f,d[x]=d[f]+1,cnt[x]=1;int tmp=-1;
 38     for(register int j=Head[x];j;j=G[j].nxt)if(y^f)dfs1(y,x),cnt[x]+=cnt[y],MAX(tmp,cnt[y])&&(son[x]=y);
 39 }
 40 void dfs2(int x,int topf){
 41     topfa[x]=topf,st[x]=tim++;if(!son[x])return;dfs2(son[x],topf);
 42     for(register int j=Head[x];j;j=G[j].nxt)if(y^fa[x]&&y^son[x])dfs2(y,y);
 43 }
 44 #undef y
 45 #define lc i<<1
 46 #define rc i<<1|1
 47 int minv[N<<1],mtag[N<<1];
 48 inline void pushup(int i){minv[i]=_min(minv[lc],minv[rc]);}
 49 inline void pushdown(int i){
 50     if(mtag[i]<INF)
 51         MIN(minv[lc],mtag[i]),MIN(minv[rc],mtag[i]),MIN(mtag[lc],mtag[i]),MIN(mtag[rc],mtag[i]),mtag[i]=INF;
 52 }
 53 void Update(int i,int L,int R,int ql,int qr,int val){//dbg(L),dbg(R),dbg(ql),dbg(qr);
 54     if(ql<=L&&qr>=R){MIN(minv[i],val),MIN(mtag[i],val);return;}
 55     int mid=L+R>>1;pushdown(i);
 56     if(ql<=mid)Update(lc,L,mid,ql,qr,val);
 57     if(qr>mid)Update(rc,mid+1,R,ql,qr,val);
 58     pushup(i);
 59 }
 60 int Query_min(int i,int L,int R,int x){
 61     if(L==R)return minv[i];
 62     int mid=L+R>>1;pushdown(i);
 63     return x<=mid?Query_min(lc,L,mid,x):Query_min(rc,mid+1,R,x);
 64 }
 65 inline void Tree_update(int x,int y,int z){
 66     while(topfa[x]^topfa[y]){
 67         if(d[topfa[x]]<d[topfa[y]])x^=y^=x^=y;
 68         Update(1,1,n-1,st[topfa[x]],st[x],z),x=fa[topfa[x]];
 69     }
 70     if(d[x]>d[y])x^=y^=x^=y;
 71     if(x^y)Update(1,1,n-1,st[x]+1,st[y],z);
 72 }
 73 inline void mst(){
 74     sort(E+1,E+m+1);int res=0;
 75     for(register int i=1;i<=n;++i)anc[i]=i;
 76     for(register int i=1;i<=m;++i)
 77         if(get_anc(E[i].u)^get_anc(E[i].v)){
 78             anc[get_anc(E[i].v)]=get_anc(E[i].u);
 79             used[E[i].id]=1,ans+=E[i].w;++res;
 80             Addedge(E[i].u,E[i].v,E[i].w);
 81         }
 82     if(res<n-1){while(q--)puts("Not connected");exit(0);}
 83     dfs1(1,0),dfs2(1,1);
 84     memset(mtag,0x3f,sizeof mtag),memset(minv,0x3f,sizeof minv);
 85     for(register int i=1;i<=m;++i){
 86         if(used[i])used[i]=d[_E[i].u]<d[_E[i].v]?_E[i].v:_E[i].u;
 87         else Tree_update(_E[i].u,_E[i].v,_E[i].w);
 88     }
 89 }
 90 int id;
 91 int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
 92     read(n);read(m);
 93     for(register int i=1;i<=m;++i)_E[i].u=read(E[i].u),_E[i].v=read(E[i].v),_E[i].w=read(E[i].w),E[i].id=i;
 94     read(q);mst();
 95     while(q--){
 96         read(id);if(!used[id]){printf("%d\n",ans);continue;}
 97         int tmp=Query_min(1,1,n-1,st[used[id]]);
 98         if(tmp<INF)printf("%d\n",ans-_E[id].w+tmp);
 99         else puts("Not connected");
100     }
101     return 0;
102 }
View Code

Reflection: Note commonly referred to this idea, that of non-tree edge to edge cover problem tree chain.

Guess you like

Origin www.cnblogs.com/saigyouji-yuyuko/p/11588941.html