NOIP2013 D1T3 货车运输

[NOIP2013T3]货车运输

背景

noip2013day1

描述

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

输入

4 3
1 2 4
2 3 3
3 1 1
3
1 3
1 4
1 3
输出

3
-1
3
备注

对于 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< 1,000, 0 < m< 50,000, 0 < q< 30,000,0 ≤ z ≤ 100,000。
这里写图片描述
队长说 也可以用树链剖分写….(可是并不会(。・・)ノ)

// by SiriusRen
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 105000
int n,m,tot=0,xx,yy,zz;
int first[N],v[N*10],next[N*10],w[N*10],f[N],dep[N],fa[N],size[N],minn[N];
int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
struct EDGE{int from,to,weight;}Edge[50500];
void add(int x,int y,int z){w[tot]=z,v[tot]=y;next[tot]=first[x];first[x]=tot++;}
bool cmp(EDGE x,EDGE y){return x.weight>y.weight;}
void dfs(int x){
    for(int i=first[x];~i;i=next[i])
        if(dep[v[i]]==-1){
            dep[v[i]]=dep[x]+1;
            fa[v[i]]=x;minn[v[i]]=w[i];
            dfs(v[i]);
        }
}
void lca(int x,int y){
    int ans=0x3fffffff;
    if(dep[x]>dep[y])swap(x,y);
    while(dep[x]!=dep[y])ans=min(minn[y],ans),y=fa[y];
    while(x!=y){
        ans=min(ans,min(minn[x],minn[y]));
        x=fa[x];y=fa[y];
    }
    printf("%d\n",ans);
    return;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)size[i]=1;
    for(int i=1;i<=n;i++)f[i]=i; 
    memset(dep,-1,sizeof(dep));
    memset(first,-1,sizeof(first));
    memset(minn,0x3f,sizeof(minn));
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&xx,&yy,&zz);
        Edge[i].from=xx;Edge[i].to=yy;Edge[i].weight=zz;
    }
    sort(Edge+1,Edge+1+m,cmp);
    for(int i=1;i<=m;i++){
        int fx=find(Edge[i].from),fy=find(Edge[i].to);
        if(fx!=fy){
            if(size[fx]>size[fy])swap(fx,fy);
            f[fx]=fy;size[fy]+=fx;
            add(fx,fy,Edge[i].weight);add(fy,fx,Edge[i].weight);
        }
    }
    dep[find(1)]=0;dfs(find(1));
    scanf("%d",&m);
    while(m--){
        scanf("%d%d",&xx,&yy);
        if(~dep[xx]&&~dep[yy])lca(xx,yy);
        else puts("-1");
    }
}

这里写图片描述

posted @ 2016-07-15 23:47  SiriusRen  阅读(143)  评论(0编辑  收藏  举报