1. 程式人生 > >「NOIP 2013」 貨車運輸

「NOIP 2013」 貨車運輸

網上 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」 貨車運輸