P1967 货车运输

题意

题目描述

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

输入输出格式

输入格式:

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

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

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

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

输出格式:

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

说明

对于 30%的数据,0 < n < 1,000,0 < m < 10,000,0 < q< 1,000;io

对于 60%的数据,0 < n < 1,000,0 < m < 50,000,0 < q< 1,000;stream

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

题解

先跑最大圣城鼠,而后因为只剩一棵树,因此跑LCA记录路径上最小值就能够了sort

然而图不必定联通...因此LCA预处理的时候要将每个以前没有处理过的点跑一遍DFS

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;

int n,m;
struct A
{
    int from;
    int to;
    int val;
}base[100100];
int fa[100100];
int to[100100],nex[100100],val[100100],head[100100],es;
int f[10010][20],minn[10010][20],deep[10010],maxh;
bool vis[10010];

bool cmp(A a,A b){return a.val>b.val;}
int find(int x){return fa[x]==x?fa[x]:fa[x]=find(fa[x]);}
void max_set_tree()
{
    int nowin=0,u,v;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        fa[i]=i;
    for(int i=1;i<=m;i++)
        cin>>base[i].from>>base[i].to>>base[i].val;
    sort(base+1,base+m+1,cmp);
    for(int i=1;i<=m;i++)
    {
        u=base[i].from;
        v=base[i].to;
        u=find(u);
        v=find(v);
        if(u==v)
            continue;
        fa[u]=v;
        ++nowin;
        to[++es]=v;
        val[es]=base[i].val;
        nex[es]=head[u];
        head[u]=es;
        to[++es]=u;
        val[es]=base[i].val;
        nex[es]=head[v];
        head[v]=es;
        if(nowin==n-1)
            break;
    }
    deep[0]=-1;
    return ;
}

void dfs(int now,int fa,int v)
{
    vis[now]=true;
    deep[now]=deep[fa]+1;
    f[now][0]=fa;
    minn[now][0]=v;
    for(int i=1;(1<<i)<=deep[now];i++)
    {
        f[now][i]=f[f[now][i-1]][i-1];
        minn[now][i]=min(minn[now][i-1],minn[f[now][i-1]][i-1]);
    }
    for(int i=head[now];i;i=nex[i])
        if(to[i]!=fa)
            dfs(to[i],now,val[i]);
    return ;
}

int lca(int x,int y)
{
    int res=2147483647;
    if(deep[x]<deep[y])
        swap(x,y);
    for(int i=maxh;i>=0;i--)
        if(deep[f[x][i]]>=deep[y])
            res=min(res,minn[x][i]),x=f[x][i];
    if(x==y)
        return res;
    for(int i=maxh;i>=0;i--)
        if(f[x][i]!=f[y][i])
        {
            res=min(res,min(minn[x][i],minn[y][i]));
            x=f[x][i];
            y=f[y][i];
        } 
    res=min(res,min(minn[x][0],minn[y][0]));
    return res;
}

void check()
{
    maxh=log(n)/log(2)+1;
    int q,x,y;
    cin>>q;
    for(int i=1;i<=q;i++)
    {
        cin>>x>>y;
        if(find(x)!=find(y))
        {
            cout<<-1<<endl;
            continue;
        }
        else
            cout<<lca(x,y)<<endl;
    }
}

int main()
{
    ios::sync_with_stdio(false);
    max_set_tree();
    for(int i=1;i<=n;i++)
        if(!vis[i]) 
            dfs(i,0,2147483647);
    check();
    return 0;
}

吐槽

我之后不再写结构体了

由于写了个结构体,WA了还找不出错来...

相关文章
相关标签/搜索