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了還找不出錯來...

相關文章
相關標籤/搜索