码迷,mamicode.com
首页 > 其他好文 > 详细

[Noip2013] 货车运输

时间:2018-08-30 22:15:01      阅读:222      评论:0      收藏:0      [点我收藏+]

标签:std   倍增   bool   不为   不能   algo   copy   fine   base   

题目描述

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

输入输出格式

输入格式:

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

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

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

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

输出格式:

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

输入输出样例

输入样例#1: 复制
4 3
1 2 4
2 3 3
3 1 1
3
1 3
1 4
1 3
输出样例#1: 复制
3
-1
3

说明

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

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

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

 


 

 

说实话这题很容易想到,像我这样的蒟蒻都能想到...

显然有一些边是没有用的,我们只需要保证图联通就行了,所以自然而然的想到生成树。

所以求一遍最大生成树,然后后面的直接类似倍增找LCA一样的写就行了,十分简单。

有个坑点,图不一定联通(废话,要不为什么输出-1)。

然而数据有在一个联通块里的, 我预处理的时候只从1开始bfs,这样gg了,必须从所有联通块都处理一遍。

轻松A掉。

 


 

 

 

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
#define reg register 
#define N 10005
#define M 50005
inline int read() {
    int res=0;char ch=getchar();
    while(!isdigit(ch))ch=getchar();
    while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
    return res;
}

int n, m;

struct edge {
    int nxt, to, val, from;
}ed[M*2];
int cnt = 1, head[N];
inline void add(int x, int y, int z)
{
    ed[++cnt] = (edge){head[x], y, z, x};
    head[x] = cnt;
}
struct date {
    int x, y, id, val;
}dat[M];
inline bool cmp(date a, date b) {
    return a.val > b.val;
}

int fa[N];
int Find(int x) {return fa[x]==x?x:fa[x]=Find(fa[x]);}

int fu[N][20], mn[N][20];
int dep[N];
bool vis[N];

inline void bfs(int cur)
{
    queue <int> q;
    q.push(cur);
    dep[cur] = 1;
    vis[cur] = 1;
    while(!q.empty())
    {
        int x = q.front();q.pop();
        for (reg int i = head[x] ; i ; i = ed[i].nxt)
        {
            int to = ed[i].to;
            if (vis[to]) continue;
            vis[to] = 1;
            dep[to] = dep[x] + 1;
            fu[to][0] = x;
            mn[to][0] = ed[i].val;
            for (reg int j = 1 ; j <= 19 ; j ++)
                fu[to][j] = fu[fu[to][j-1]][j-1], mn[to][j] = min(mn[to][j-1], mn[fu[to][j-1]][j-1]);
            q.push(to);
        }
    }
}

inline int solve(int x, int y)
{
    int res = 1e9;
    if (dep[x] < dep[y]) swap(x, y);
    for (reg int i = 19 ; i >= 0 ; i --)
        if (dep[fu[x][i]] >= dep[y]) res = min(res, mn[x][i]), x = fu[x][i];
    if (x == y) return res;
    for (reg int i = 19 ; i >= 0 ; i --)
        if (fu[x][i] != fu[y][i]) res = min(res, min(mn[x][i], mn[y][i])), x = fu[x][i], y = fu[y][i];
    res = min(res, min(mn[x][0], mn[y][0]));
    return res;
}

int main()
{
    n = read(), m = read();
    for (reg int i = 1 ; i <= m ; i ++)
    {
        int x = read(), y = read(), z = read();
        dat[i] = (date){x, y, i, z};
    }
    sort(dat + 1, dat + 1 + m, cmp);
    int k = 0;
    for (reg int i = 1 ; i <= n ; i ++) fa[i] = i;
    for (reg int i = 1 ; i <= m ; i ++)
    {
        int x = dat[i].x, y = dat[i].y;
        int fx = Find(x), fy = Find(y);
        if (fx == fy) continue;
        add(x, y, dat[i].val), add(y, x, dat[i].val);
        fa[fx] = fy;
        k++;
        if (k == n - 1) break;
    }
    memset(mn, 0x3f, sizeof mn);
    for (reg int i = 1 ; i <= n ; i ++)
        if (!vis[i]) bfs(i);
    int q = read();
    while(q--)
    {
        int x = read(), y = read();
        if (Find(x) != Find(y)) {puts("-1"); continue;}
        printf("%d\n", solve(x, y));
    }
    return 0;
}

 

 

 

[Noip2013] 货车运输

标签:std   倍增   bool   不为   不能   algo   copy   fine   base   

原文地址:https://www.cnblogs.com/BriMon/p/9562879.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!