「NOIP 2013」 貨車運輸
阿新 • • 發佈:2019-02-13
網上 bool getchar 鏈接 www mes turn struct noi
題目鏈接
戳我
\(Solution\)
這一道題直接用\(kruskal\)重構樹就好了,這裏就不詳細解釋\(kruskal\)重構樹了,如果不會直接去網上搜就好了.接下來講講詳細過程.
- 首先構建\(kruskal\)重構樹.
對於詢問直接求\(lca\)就可以了,如果沒有\(lca\)輸出\(-1\),否則輸入\(lca\)上的權值就好了,不是很難.
\(Code\)
#include<bits/stdc++.h> using namespace std; const int N=200011; int read(){ int x=0,f=1;char c=getchar(); while(c<'0'||c>'9') f=(c=='-')?-1:1,c=getchar(); while(c>='0'&&c<='9') x=x*10+c-48,c=getchar(); return f*x; } struct node1 { int to,next; }e[500001]; struct node{ int x,y,v; }b[N]; int res,cnt,n,m,t,pre[N],head[N],vis[N]; int f[N][21],dep[N],val[N],bin[101]; void add(int x,int y){ e[++cnt].to=y,e[cnt].next=head[x],head[x]=cnt; } int find(int x){ return pre[x]==x?x:pre[x]=find(pre[x]); } bool cmp(const node & a , const node & b ){ return a.v>b.v; } void dfs(int k){ vis[k]=1; for(int j=1;j<=19;j++) f[k][j]=f[f[k][j-1]][j-1]; for(int i=head[k];i;i=e[i].next){ int v=e[i].to; f[v][0]=k,dep[v]=dep[k]+1; dfs(v); } } int lca(int x,int y){ if(dep[x]<dep[y]) swap(x,y); // cout<<dep[x]<<" "<<dep[y]; for(int i=19;i>=0;i--) if(dep[x]-(1<<i)>=dep[y]) x=f[x][i]; if(x==y) return y; for(int i=19;i>=0;i--){ if(f[x][i]==f[y][i]||!f[y][i]||!f[x][i]) continue; x=f[x][i],y=f[y][i]; } return f[x][0]; } void build(){ res=n,sort(b+1,b+1+m,cmp); for(int i=1;i<=m;i++){ int fx=find(b[i].x),fy=find(b[i].y); if(fx!=fy) val[++res]=b[i].v,pre[fx]=res,pre[fy]=res,add(res,fx),add(res,fy); if(res==n*2-1) break; } } int main(){ n=read(),m=read(),bin[1]=0; for(int i=1;i<n*2;i++) pre[i]=i; for(int i=1;i<=19;i++) bin[i]=bin[i-1]<<1; for(int i=1;i<=m;i++) b[i].x=read(),b[i].y=read(),b[i].v=read(); build(); for(int i=1;i<=n;i++) if(!vis[i]) dfs(find(i)); t=read(); while(t--){ int x=read(),y=read(); int p=lca(x,y); // cout<<find(x)<<" "<<find(y)<<endl; if(p==0) cout<<"-1\n"; else cout<<val[p]<<endl; } }
「NOIP 2013」 貨車運輸