8.13模拟赛

T1 HOTEL 

题目大意:

思路:

T2 Chips Challenge

题目大意:

思路:

T3 Mst

题目大意:

给出一个N个点M条边的无向带权图,以及Q个询问,每次询问在图中删掉一条边后图的最小生成树

思路:

先搞出最小生成树

如果删的边不是树边 不影响

如果是即我们需要一条非树边将这两个联通块联通,可以将所有非树边按照从大至小的顺序,将这个边的两个端点在树上的路径的答案修改为该边的权值

每次询问的时候查询这条边的答案

  1 #include<iostream>
  2 #include<cmath>
  3 #include<algorithm>
  4 #include<cstdio>
  5 #include<cstring>
  6 #include<cstdlib>
  7 #include<queue>
  8 #include<vector>
  9 #include<set>
 10 #define MAXN 50100
 11 #define ll long long
 12 #define inf 2139062143
 13 using namespace std;
 14 inline int read()
 15 {
 16     int x=0,f=1;char ch=getchar();
 17     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
 18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
 19     return x*f;
 20 }
 21 int n,m,fst[MAXN],nxt[MAXN<<1],to[MAXN<<1],cnt,etr[MAXN<<1],hvs[MAXN];
 22 int fa[MAXN],trs[MAXN<<1],hsh[MAXN],sz[MAXN],dep[MAXN],bl[MAXN],ans,f;
 23 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
 24 struct edge{int u,v,val,id;}e[MAXN<<1];
 25 bool cmp(edge a,edge b) {return a.val<b.val;}
 26 int find(int x) {return x==fa[x]?x:fa[x]=find(fa[x]);}
 27 bool ok(int a,int b)
 28 {
 29     int f1=find(a),f2=find(b);
 30     if(f1!=f2) {fa[f1]=f2;return 0;}
 31     return 1;
 32 }
 33 void kruskal(int res)
 34 {
 35     sort(e+1,e+m+1,cmp);
 36     for(int i=1;i<=m;i++)
 37         if(!ok(e[i].u,e[i].v)) {res++,ans+=e[i].val;add(e[i].u,e[i].v);add(e[i].v,e[i].u);trs[e[i].id]=i,etr[i]=1;}
 38     if(res!=n-1) f=1;
 39 }
 40 void dfs(int x)
 41 {
 42     sz[x]=1,dep[x]=dep[fa[x]]+1;
 43     for(int i=fst[x];i;i=nxt[i])
 44         if(to[i]!=fa[x]) {fa[to[i]]=x;dfs(to[i]);sz[x]+=sz[to[i]];}
 45 }
 46 void Dfs(int x,int anc)
 47 {
 48     hsh[x]=++cnt,bl[x]=anc;
 49     for(int i=fst[x];i;i=nxt[i])
 50         if(dep[to[i]]>dep[x]&&sz[hvs[x]]<sz[to[i]]) hvs[x]=to[i];
 51     if(!hvs[x]) {hvs[x]=x;return ;}Dfs(hvs[x],anc);
 52     for(int i=fst[x];i;i=nxt[i])
 53         if(dep[to[i]]>dep[x]&&to[i]!=hvs[x]) {Dfs(to[i],to[i]);}
 54 }
 55 int mn[MAXN<<2],tag[MAXN<<2];
 56 void pshd(int k,int l,int r,int mid)
 57 {
 58     tag[k<<1]=tag[k<<1|1]=tag[k];
 59     mn[k<<1]=tag[k],mn[k<<1|1]=tag[k],tag[k]=0;
 60 }
 61 void mdf(int k,int l,int r,int a,int b,int x)
 62 {
 63     if(l==a&&r==b) {mn[k]=tag[k]=x;return ;}
 64     int mid=(l+r)>>1;
 65     if(tag[k]) pshd(k,l,r,mid);
 66     if(mid>=b) mdf(k<<1,l,mid,a,b,x);
 67     else if(mid<a) mdf(k<<1|1,mid+1,r,a,b,x);
 68     else {mdf(k<<1,l,mid,a,mid,x);mdf(k<<1|1,mid+1,r,mid+1,b,x);}
 69     mn[k]=min(mn[k<<1],mn[k<<1|1]);
 70 }
 71 int query(int k,int l,int r,int x)
 72 {
 73     if(l==r) return mn[k];
 74     int mid=(l+r)>>1;
 75     if(tag[k]) pshd(k,l,r,mid);
 76     if(mid>=x) return query(k<<1,l,mid,x);
 77     else query(k<<1|1,mid+1,r,x);
 78 }
 79 void tr_mdf(int a,int b,int x)
 80 {
 81     while(bl[a]!=bl[b])
 82     {
 83         if(dep[bl[a]]<dep[bl[b]]) swap(a,b);
 84         mdf(1,1,n,hsh[bl[a]],hsh[a],x);
 85         a=fa[bl[a]];
 86     }
 87     if(dep[a]<dep[b]) swap(a,b);
 88     if(a!=b) mdf(1,1,n,hsh[hvs[b]],hsh[a],x);
 89 }
 90 int main()
 91 {
 92     n=read(),m=read();
 93     for(int i=1;i<=n;i++) fa[i]=i;
 94     for(int i=1;i<=m;i++) e[i].id=i,e[i].u=read(),e[i].v=read(),e[i].val=read();
 95     kruskal(0);fa[1]=1;dfs(1);cnt=0;Dfs(1,1);int T=read(),x;
 96     if(!f) for(int i=m;i;i--) if(!etr[i]) tr_mdf(e[i].u,e[i].v,e[i].val);
 97     while(T--)
 98     {
 99         x=trs[read()];
100         if(f) {puts("Not connected");continue;}
101         if(etr[x])
102         {
103             if(query(1,1,n,max(hsh[e[x].u],hsh[e[x].v]))) printf("%d\n",ans-e[x].val+query(1,1,n,max(hsh[e[x].u],hsh[e[x].v])));
104             else puts("Not connected");
105         }
106         else printf("%d\n",ans);
107     }
108 }
View Code

猜你喜欢

转载自www.cnblogs.com/yyc-jack-0920/p/9468452.html