xsy 2018 【NOIP2013】货车运输

【NOIP2013】货车运输

Description

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

Input

第一行有两个用一个空格隔开的整数 n,m,表示A国有n座城市和m条道路。
接下来m行每行3个整数x,y,z,每两个整数之间用一个空格隔开,表示从x号城市到y号城市有一条限重为z的道路。注意:x不等于y,两座城市之间可能有多条道路。
接下来一行有一个整数q,表示有q辆货车需要运货。
接下来q行,每行两个整数x,y之间用一个空格隔开,表示一辆货车需要从x城市运输货物到y城市,注意:x不等于y。

Output

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

Sample Input

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

Sample Output

3
-1
3

HINT

对于30%的数据,1n10001m100001q1000
对于60%的数据,1n10001m500001q1000
对于100%的数据,1n100001m500001q300000z100000

题解思路

首先,如果两点之间某路径上最小的一条边不在该图的最大生成树上,那么在这个图中,一定有一条路径,其中每一条边的值都大于等于那条边的值。

所以只需要求出最大生成树后再用LCA维护最小值即可。

时间复杂度:O(nlogn)

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct data{
    int x,y,v;
}t[50001],d[20001];
int n,m,s[10001][21],f[10001][21],fa[10001],h[10001],cnt,fx,fy,ans,p[10001],id[10001],x,y;
bool cmp(data a,data b){
    return a.v>b.v;
}
int father(int a){
    if(fa[a]!=a)fa[a]=father(fa[a]);
    return fa[a];
}
void add(int a,int b,int c){
    cnt++;
    d[cnt].x=b;
    d[cnt].y=h[a];
    d[cnt].v=c;
    h[a]=cnt;
}
void dfs(int a){
    for(int i=1;i<=20;i++){
        f[a][i]=f[f[a][i-1]][i-1];
        s[a][i]=min(s[a][i-1],s[f[a][i-1]][i-1]);
    }
    for(int i=h[a];i;i=d[i].y){
        if(!p[d[i].x]){
            p[d[i].x]=p[a]+1;
            f[d[i].x][0]=a;
            s[d[i].x][0]=d[i].v;
            id[d[i].x]=id[a];
            dfs(d[i].x);
        }
    }
}
void lca(int a,int b){
    if(p[a]>p[b]){
        for(int i=20;i>=0;i--){
            if(p[f[a][i]]>=p[b]){
                ans=min(ans,s[a][i]);
                a=f[a][i];
            }
        }
    }
    if(p[a]<p[b]){
        for(int i=20;i>=0;i--){
            if(p[f[b][i]]>=p[a]){
                ans=min(ans,s[b][i]);
                b=f[b][i];
            }
        }
    }
    for(int i=20;i>=0;i--){
        if(f[a][i]!=f[b][i]){
            ans=min(ans,s[a][i]);
            ans=min(ans,s[b][i]);
            a=f[a][i];
            b=f[b][i];
        }
    }
    if(a!=b){
        ans=min(ans,s[a][0]);
        ans=min(ans,s[b][0]);
    }
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)scanf("%d%d%d",&t[i].x,&t[i].y,&t[i].v);
    for(int i=1;i<=n;i++)fa[i]=i;
    sort(t+1,t+m+1,cmp);
    for(int i=1;i<=m;i++){
        fx=father(t[i].x);
        fy=father(t[i].y);
        if(fx!=fy){
            fa[fx]=fy;
            add(t[i].x,t[i].y,t[i].v);
            add(t[i].y,t[i].x,t[i].v);
        }
    }
    for(int i=1;i<=n;i++){
        if(!id[i]){
            p[i]=1;
            id[i]=i;
            dfs(i);
        }
    }
    scanf("%d",&m);
    for(int i=1;i<=m;i++){
        ans=10000000;
        scanf("%d%d",&x,&y);
        if(id[x]==id[y]){
            lca(x,y);
            printf("%d\n",ans);
        }else printf("-1\n");
    }
}

  

 

猜你喜欢

转载自www.cnblogs.com/ez-syh/p/11615450.html