zoukankan      html  css  js  c++  java
  • 「NOIP 2013」 货车运输

    题目链接

    戳我

    (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
    ";
    		else
    			cout<<val[p]<<endl;
    	}
    }
    
    
  • 相关阅读:
    postgresql 高可用 etcd + patroni 之八 haproxy + keepalived
    postgresql 高可用 etcd + patroni 之七 haproxy
    postgresql 索引之 gin
    postgresql 索引之 btree
    postgresql 物理备份 barman 之 rsync/ssh backup
    postgresql 物理备份 barman 之 streaming backup
    postgresql 物理备份 barman 之 安装
    postgresql 的 .pgpass密码文件的使用
    postgresql 的 pg_hba.conf 的行记录顺序
    ubuntu 16.04 进入单用户模式
  • 原文地址:https://www.cnblogs.com/hbxblog/p/10371570.html
Copyright © 2011-2022 走看看