uoj 30 tourists
题目大意:
一个无向图 每个点有权值 支持两个操作
1 修改某个点的权值
2 查询a-b所有简单路径的点上的最小值
思路:
可以把图变成圆方树 然后树链剖分 维护
对于每个方点使用可删堆维护
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<cstring> 6 #include<algorithm> 7 #include<vector> 8 #include<queue> 9 #define inf 2139062143 10 #define ll long long 11 #define MAXN 200100 12 #define V g2.to[i] 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;if(ch=='A'||ch=='C') return ch-'A';ch=getchar();} 18 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 19 return x*f; 20 } 21 int n,m,Q,tot; 22 struct graph 23 { 24 int cnt,fst[MAXN],nxt[MAXN<<1],to[MAXN<<1]; 25 graph(){memset(fst,0,sizeof(fst));cnt=0;} 26 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;} 27 }g1,g2; 28 int st[MAXN],dfn[MAXN],low[MAXN],top,stp,val[MAXN]; 29 int hsh[MAXN],dep[MAXN],bl[MAXN],fa[MAXN],sz[MAXN]; 30 priority_queue <int,vector<int>,greater<int> > q[MAXN],d[MAXN]; 31 void tarjan(int x) 32 { 33 dfn[x]=low[x]=++stp,st[++top]=x; 34 sz[x]=1;int now=0; 35 for(int i=g1.fst[x];i;i=g1.nxt[i]) 36 if(!dfn[g1.to[i]]) 37 { 38 tarjan(g1.to[i]);low[x]=min(low[x],low[g1.to[i]]); 39 if(low[g1.to[i]]<dfn[x]) continue;m++; 40 do{now=st[top--],sz[m]+=sz[now];g2.add(m,now);} 41 while(now!=g1.to[i]); 42 g2.add(x,m);sz[x]+=sz[m]; 43 } 44 else low[x]=min(low[x],dfn[g1.to[i]]); 45 } 46 void dfs(int x) 47 { 48 for(int i=g2.fst[x];i;i=g2.nxt[i]) {dep[V]=dep[x]+1,fa[V]=x;dfs(V);} 49 } 50 void dfs(int x,int anc) 51 { 52 hsh[x]=++tot,bl[x]=anc;int hvs=0,tmp= x<=n; 53 for(int i=g2.fst[x];i;i=g2.nxt[i]) 54 { 55 if(sz[V]>sz[hvs]) hvs=V; 56 if(!tmp) q[x].push(val[V]); 57 } 58 if(!hvs) return ;dfs(hvs,anc); 59 for(int i=g2.fst[x];i;i=g2.nxt[i]) 60 if(V!=hvs) dfs(V,V); 61 } 62 int mn[MAXN<<2]; 63 void mdf(int k,int l,int r,int x,int w) 64 { 65 if(l==r) {mn[k]=w;return ;} 66 int mid=(l+r)>>1; 67 if(x<=mid) mdf(k<<1,l,mid,x,w); 68 else mdf(k<<1|1,mid+1,r,x,w); 69 mn[k]=min(mn[k<<1],mn[k<<1|1]); 70 } 71 int query(int k,int l,int r,int a,int b) 72 { 73 if(l==a&&r==b) return mn[k]; 74 int mid=(l+r)>>1; 75 if(b<=mid) return query(k<<1,l,mid,a,b); 76 else if(a>mid) return query(k<<1|1,mid+1,r,a,b); 77 else return min(query(k<<1,l,mid,a,mid),query(k<<1|1,mid+1,r,mid+1,b)); 78 } 79 void pop(int x) 80 { 81 while(q[x].top()==d[x].top()&&!d[x].empty()) {q[x].pop();d[x].pop();} 82 } 83 int main() 84 { 85 n=read(),m=read(),Q=read();int a,b,c,res; 86 for(int i=1;i<=n;i++) val[i]=read(); 87 while(m--) {a=read(),b=read();g1.add(a,b);g1.add(b,a);} 88 m=n;tarjan(1);dfs(1);dfs(1,1); 89 memset(mn,127,sizeof(mn)); 90 for(int i=1;i<=m;i++) 91 if(i>n) mdf(1,1,m,hsh[i],q[i].top()); 92 else mdf(1,1,m,hsh[i],val[i]); 93 while(Q--) 94 { 95 c=read(),a=read(),b=read(),res=inf; 96 if(c^2) 97 { 98 while(bl[a]!=bl[b]) 99 { 100 if(dep[bl[a]]<dep[bl[b]]) swap(a,b); 101 res=min(res,query(1,1,m,hsh[bl[a]],hsh[a])); 102 a=fa[bl[a]]; 103 } 104 if(dep[a]>dep[b]) swap(a,b); 105 if(a>n) res=min(res,val[fa[a]]); 106 res=min(res,query(1,1,m,hsh[a],hsh[b])); 107 printf("%d\n",res);continue; 108 } 109 if(a==1) {val[a]=b;mdf(1,1,m,hsh[a],b);continue;} 110 d[fa[a]].push(val[a]);q[fa[a]].push(b); 111 if(b!=q[fa[a]].top()&&val[a]!=q[fa[a]].top()) {val[a]=b;mdf(1,1,m,hsh[a],b);continue;} 112 pop(fa[a]);val[a]=b;mdf(1,1,m,hsh[a],val[a]);mdf(1,1,m,hsh[fa[a]],q[fa[a]].top()); 113 } 114 }