noip2013货车运输

P1967 货车运输

题目描述

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

输入输出格式

输入格式:

输入文件名为 truck.in。

输入文件第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道

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

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

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

输出格式:

输出文件名为 truck.out。

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

车不能到达目的地,输出-1。

输入输出样例

输入样例#1:

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

输出样例#1:

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 < 10,000,0 < m < 50,000,0 < q< 30,000,0 ≤ z ≤ 100,000。

【题目解析】

代码简单,ans1如果能够联通的就用它记下该次询问的编号,更新答案时有编号的更新,没有编号的也就是无法连通的 ans仍为-1,

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
vector <int> ans1[10010];
int m,n,q;
int father[10010],s[30010],t[30010];
bool vist[30010];
int ans[30010];
struct node{
    int x,y,z;
}a[51000];
int getfa(int x)//找爹 
{
    if(father[x]==x) return x;
    return father[x]=getfa(father[x]);
}
bool jianb(int x,int y)//建边 
{
    int a=getfa(x),b=getfa(y);
    if(a!=b)
    {
        father[b]=a;
        return false;
    }
    return true;
}
int cmp(node xx,node yy)//根据边权的大小排序 
{
    return xx.z>yy.z;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        father[i]=i;
    for(int i=1;i<=m;i++)
        scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
    sort(a+1,a+m+1,cmp);
    scanf("%d",&q);
    for(int i=1;i<=q;i++)
        scanf("%d%d",&s[i],&t[i]);
    for(int i=1;i<=m;i++)
    {
        if(getfa(a[i].x)!=getfa(a[i].y))
            jianb(a[i].x,a[i].y);
        if(i==m || i%100==0)
        {
            for(int j=1;j<=q;j++)
                if(vist[j]==0 && getfa(s[j])==getfa(t[j]))
                    vist[j]=1,
                    ans1[(i-1)/100].push_back(j);
        }
    }
    for(int i=1;i<=n;i++)
        father[i]=i;
    memset(ans,-1,sizeof(ans));
    for(int i=1;i<=m;i++)
    {
        if(getfa(a[i].x)!=getfa(a[i].y))
           jianb(a[i].x,a[i].y);
        int num=(i-1)/100;
        for(int j=0;j<ans1[num].size();j++)
        {
            if(ans[ans1[num][j]]==-1&&getfa(s[ans1[num][j]])==getfa(t[ans1[num][j]]))
                ans[ans1[num][j]]=a[i].z;
        }
    }
    for(int i=1;i<=q;i++)
        printf("%d
",ans[i]);
    return 0;
}
原文地址:https://www.cnblogs.com/xiaoningmeng/p/5788752.html