zoukankan      html  css  js  c++  java
  • [noip2013] 货车运输(最大生成树+并查集+LCA) 2017-06-02 15:18 56人阅读 评论(0) 收藏

    货车运输

    描述

    A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。

    格式

    输入格式

    第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道路。

    接下来 m 行每行 3 个整数 x、y、z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条限重为 z 的道路。注意:x 不等于 y,两座城市之间可能有多条道路。

    接下来一行有一个整数 q,表示有 q 辆货车需要运货。

    接下来 q 行,每行两个整数 x、y,之间用一个空格隔开,表示一辆货车需要从 x 城市运输货物到 y 城市,注意:x 不等于 y。

    输出格式

    输出共有 q 行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。如果货车不能到达目的地,输出-1。

    样例1

    样例输入1

    4 3 
    1 2 4 
    2 3 3 
    3 1 1 
    3
    1 3 
    1 4 
    1 3
    

    样例输出1

    3
    -1
    3
    

    限制

    每个测试点1s。

    提示

    对于 30%的数据,0 < n < 1,000,0 < m < 10,000,0 < q < 1,000; 
    对于 60%的数据,0 < n < 1,000,0 < m < 50,000,0 < q < 1,000; 
    对于 100%的数据,0 < n < 10,000,0 < m < 50,000,0 < q < 30,000,0 ≤ z ≤ 100,000。

    来源

    NOIP 2013 提高组 Day 1


    思路

    kruska算法+并查集 将边权值由大到小排 建立边数最多为n-1的最大生成树

    用前向星 建树后 查询m,n

    就查询mn的LCA  输出 min(m到LCA的路中最短的一段,n到LCA的路中最短的一段)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #define M 50005
    #define N 10005
    #define inf 999999999
    using namespace std;
    int fa[N],cnt=0,tot=0,deep[N],val[N][20],f[N][20],head[N];
    bool vis[N];
    int n,m;
    struct node{
    	int l;
    	int r;
    	int w;
    }e[M];
    struct Tree{
    	int to,v,next;
    }a[2*N];
    void insert(){
    	int x,y,z;
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;i++){
    		scanf("%d%d%d",&x,&y,&z);
    		e[i].l=x;e[i].r=y;e[i].w=z;
    
    	}
    }
    void ins(int u,int v,int w)
    {
    	a[++cnt].to=v;
    	a[cnt].v=w;
    	a[cnt].next=head[u];
    	head[u]=cnt;
    }
    void inserttree(int u,int v,int w)
    {
    	ins(u,v,w);
    	ins(v,u,w);
    }
    bool cmp(node xx,node yy){
    	return xx.w>yy.w;
    }
    int findf(int x){
    	if(fa[x]==x) return x;
    	fa[x]=findf(fa[x]);
    	return fa[x];
    }
    void merge(int x,int y){
    	int fx=findf(x);
    	int fy=findf(y);
    	fa[fx]=fy;
    }
    void dfs(int x){
    	vis[x]=1;
    	for(int i=1;i<=20;i++){
            if(deep[x]<(1<<i))break;
    		f[x][i]=f[f[x][i-1]][i-1];
            val[x][i]=min(val[x][i-1],val[f[x][i-1]][i-1]);
    	}
    	for(int i=head[x];i>0;i=a[i].next){
    		int v=a[i].to;
    		if(vis[v]) continue;
            f[v][0]=x;
            val[v][0]=a[i].v;
            deep[v]=deep[x]+1;
            dfs(v);
    	}
    }
    int lca(int x,int y){
    	if(deep[x]<deep[y]) swap(x,y);
    	int t=deep[x]-deep[y];
    	for(int i=0;i<=16;i++){
    		if(t&(1<<i))
    		x=f[x][i];
    	}
    	for(int i=16;i>=0;i--){
    		if(f[x][i]!=f[y][i]){
    			x=f[x][i];
    			y=f[y][i];
    		}
    	}
    	if(x==y) return x;
    	return f[x][0];
    }
    int ask(int x,int y){
    	int mn=inf;
    	int t=deep[x]-deep[y];
    	for(int i=0;i<=16;i++)
    	{
    		if(t&(1<<i))
    		{
    		   mn=min(mn,val[x][i]);
    		   x=f[x][i];
    		}
    	}
    	return mn;
    }
    int main(){
    	insert();
    	sort(e+1,e+1+m,cmp);
    	for(int i=1;i<=n;i++)
            fa[i]=i;
    	for(int i=1;i<=m;i++){
    		int x=e[i].l;
    		int y=e[i].r;
    		if(findf(x)!=findf(y))
    		{
    			merge(x,y);
    			inserttree(x,y,e[i].w);
    			tot++;
    			if(tot==n-1) break;
    		}
    	}
    	for(int i=1;i<=n;i++)
            if(!vis[i])dfs(i);
    	int q;
    	scanf("%d",&q);
    	for(int i=1;i<=q;i++){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		if(findf(x)!=findf(y))
    		{printf("-1
    ");continue;}
    		else {
    			int t=lca(x,y);
    			printf("%d
    ",min(ask(x,t),ask(y,t)));
    		}
    	}
    	return 0;
    }
    


  • 相关阅读:
    Ahoi2013 作业
    bzoj 2502 清理雪道 (有源汇上下界最小流)
    zoj 3229 Shoot the Bullet(有源汇上下界最大流)
    TCP协议和socket API 学习笔记
    http、TCP/IP协议与socket之间的区别
    ios多线程和进程的区别(转载)
    iOS进程间通信之CFMessagePort
    功能强大的Xcode辅助工具Faux Pas:帮你找到各种隐形的bug
    [深入浅出Cocoa]iOS程序性能优化
    IOS之禁用UIWebView的默认交互行为
  • 原文地址:https://www.cnblogs.com/xljxlj/p/7183630.html
Copyright © 2011-2022 走看看