您的位置:首页 > 其它

NOIP2013 货车运输

2016-08-19 18:03 246 查看

题目描述

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。

思路

没什么好说的

就是最大生成树和倍增LCA

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#define M 50000
using namespace std;
int n,m,q;
struct nb{
int to;
int next;
int val;
};
struct nba {
int x,y,z;
bool operator < (nba l) const {
return z>l.z;
}
};
nba a[M];
nb b[M];
int fa[M],f[M][21],deep[M],v[M][21];
int cnt,head[M];
bool vis[M];
inline int read(int&x) {
x=0;char c=getchar();
while(c>'9'||c<'0') c=getchar();
while(c>='0'&&c<='9') x=10*x+c-48,c=getchar();
}
inline int find(int x) {
if(x==fa[x]) return x;
fa[x]=find(fa[x]);
return fa[x];
}
inline void add(int x,int y,int z) {
b[++cnt].to=y;
b[cnt].val=z;
b[cnt].next=head[x];
head[x]=cnt;
}
inline void dfs(int now,int from,int dep,int w) {
f[now][0]=from;
deep[now]=dep;
for(int i=head[now];i;i=b[i].next) {
int j=b[i].to;
if(j!=from)
{
v[j][0]=b[i].val;
dfs(j,now,dep+1,b[i].val);
}
}
}
inline int LCA(int a,int b) {
int ans=1e8;
if(deep[a]<deep[b]) swap(a,b);
int t=deep[a]-deep[b];
for(int i=0;i<=20;i++)
if((1<<i)&t) {
ans=min(ans,v[a][i]);
a=f[a][i];
}
if(a==b) return ans;
for(int i=20;i>=0;i--)
if(f[a][i]!=f[b][i]) {
ans=min(min(ans,v[a][i]),v[b][i]);
a=f[a][i];
b=f[b][i];
}
ans=min(min(ans,v[a][0]),v[b][0]);
return ans;
}
int main() {
freopen("jh.in","r",stdin);
read(n);read(m);
for(int i=1;i<=m;i++) read(a[i].x),read(a[i].y),read(a[i].z);
sort(a+1,a+m+1);
int tot=0;
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=1;i<=m;i++) {
int t1=a[i].x;int t2=a[i].y;int t3=a[i].z;
int f1=find(t1);
int f2=find(t2);
if(f1!=f2) {
fa[f1]=f2;
add(t1,t2,t3);
add(t2,t1,t3);
tot++;
if(tot==n-1) break;
}
}
dfs(1,1,0,0);
for(int j=1;j<=20;j++)
for(int i=1;i<=n;i++) {
f[i][j]=f[f[i][j-1]][j-1];
v[i][j]=min(v[i][j-1],v[f[i][j-1]][j-1]);
}
read(q);
for(int i=1;i<=q;i++) {
int x,y;
read(x);read(y);
if(find(x)!=find(y)) printf("-1\n");
else {
int ans=LCA(x,y);
printf("%d\n",ans);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: