NOIP 2013 提高组 Day1T3 货车运输【最大生成树】【LCA】

原创 2018年04月17日 18:31:13

题目索引:http://oi.nks.edu.cn/zh/Problem/Details/2495

P2495【NOIP2013-D1T3】货车运输
时间限制 : 10000 MS   空间限制 : 128000 KB
问题描述

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

输入格式

第一行有两个用一个空格隔开的整数 n,m,表示 A 国有n座城市和m条道路。
接下来m行,每行3个整数x,y,z,表示从x号城市到y号城市有一条限重为z的道路(x≠y,两座城市之间可能有多条道路)
接下来一行有一个整数 q,表示有 q 辆货车需要运货。
接下来q行,每行两个整数x,y,之间用一个空格隔开,表示一辆货车需要从x城市运输货物到y城市(x≠y)。

输出格式

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

样例输入 1

4 3 
1 2 4 
2 3 3 
3 1 1 

1 3 
1 4 
1 3 

样例输出 1

3
-1
3

样例输入 2

5 7
4 3 4440
3 1 22348
1 3 28368
2 4 25086
5 3 6991
4 3 10638
3 1 11106
4
4 5
1 3
5 4
2 5

样例输出 2

6991
28368
6991
6991

提示

对于 30%的数据,1<=n<=1000,1<=m<=10000,1<=q<=1000;
对于 60%的数据,1<=n<=1000,1<=m<=50000,1<=q<=1000;
对于 100%的数据,1<=n<=10000,1<=m<=50000,1<=q<=30000,0<=z<=100000。


题目分析:

       不得不说,这道题其实两个模板。题目中要求最多能运多重的货物,很容易想到用Kurskal跑一次最大生成树建图。然后对于每个询问其实就是计算LCA。于是这道题似乎就解完了。->好水的题解->

代码如下:

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define DB double
#define SG string
#define LL long long
#define Fp(A,B,C,D) for(A=B;A<=C;A+=D)
#define Fm(A,B,C,D) for(A=B;A>=C;A-=D)
#define Clear(A) memset(A,0,sizeof(A))
using namespace std;
const LL Max=1e4+5;
const LL Mod=1e9+7;
const LL Inf=1e18;
struct Node{
	LL X,Y,Z;
}A[(Max<<1)+(Max<<2)];
struct Root{
	LL Next,To,Edge;
}G[Max<<1];
LL N,M,Q,Cnt,Tot,Deep[Max],Head[Max],Vis[Max],F[Max],Fa[Max][20],D[Max][20];
inline LL Read(){
	LL X=0;char CH=getchar();bool F=0;
	while(CH>'9'||CH<'0'){if(CH=='-')F=1;CH=getchar();}
	while(CH>='0'&&CH<='9'){X=(X<<1)+(X<<3)+CH-'0';CH=getchar();}
	return F?-X:X;
}
inline void Write(LL X){
	if(X<0)X=-X,putchar('-');
	if(X>9)Write(X/10);
	putchar(X%10+48);
}
void Insert(LL X,LL Y,LL Z){
	G[++Cnt].To=Y;G[Cnt].Edge=Z;G[Cnt].Next=Head[X];Head[X]=Cnt;
}
LL Find(LL X){
	return F[X]==X?X:F[X]=Find(F[X]);
}
LL Cmp(Node P,Node Q){
	return P.Z>Q.Z;
}
void DFS(LL X){
	LL I,J,K;
	Vis[X]=1;
	Fp(I,1,16,1){
		if(Deep[X]<(1<<I)){
			break;
		}
		Fa[X][I]=Fa[Fa[X][I-1]][I-1];
		D[X][I]=min(D[X][I-1],D[Fa[X][I-1]][I-1]);
	}
	for(I=Head[X];I;I=G[I].Next){
		if(Vis[G[I].To]){
			continue;
		}
		Fa[G[I].To][0]=X;
		D[G[I].To][0]=G[I].Edge;
		Deep[G[I].To]=Deep[X]+1;
		DFS(G[I].To);
	}
}
LL LCA(LL X,LL Y){
	LL I,J,K,T;
	if(Deep[X]<Deep[Y]){
		swap(X,Y);
	}T=Deep[X]-Deep[Y]; 
	Fp(I,0,16,1){
		if((1<<I)&T){
			X=Fa[X][I];
		}
	}
	Fm(I,16,0,1){
		if(Fa[X][I]!=Fa[Y][I]){
			X=Fa[X][I];
			Y=Fa[Y][I];
		}
	}
	if(X==Y){
		return Y;
	}return Fa[X][0];
}
LL Get(LL P,LL Q){
	LL I,J,K,T=abs(Deep[P]-Deep[Q]),Ans=Inf;
	Fp(I,0,16,1){
		if(T&(1<<I)){
			Ans=min(Ans,D[P][I]);
			P=Fa[P][I];
		}
	}
	return Ans;
}
int main(){
	LL I,J,K;
	memset(D,66,sizeof(D));
	N=Read(),M=Read();
	Fp(I,1,N,1){
		F[I]=I;
	}
	Fp(I,1,M,1){
		A[I].X=Read(),A[I].Y=Read(),A[I].Z=Read();
	}sort(A+1,A+1+M,Cmp);
	Fp(I,1,M,1){
		LL X=A[I].X,Y=A[I].Y;
		LL Fx=Find(X),Fy=Find(Y);
		if(Fx!=Fy){
			F[Fx]=Fy;
			Insert(X,Y,A[I].Z);
			Insert(Y,X,A[I].Z);
			Tot++;
			if(Tot==N-1){
				break;
			}
		}
	}
	Fp(I,1,N,1){
		if(!Vis[I]){
			DFS(I);
		}
	}
	Q=Read();
	Fp(I,1,Q,1){
		LL X=Read(),Y=Read();
		if(Find(X)!=Find(Y)){
			puts("-1");
		} else {
			LL T=LCA(X,Y);
			Write(min(Get(X,T),Get(Y,T)));puts("");
		}
	}
	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yanyidu/article/details/79978830

NOIP2013 货车运输 解题报告(最大生成树+倍增lca)

在线评测: http://codevs.cn/problem/3287/ 整体思路: 我们先看一下题,题中需要使道路上的边的最小值尽可能的大,而且并不关心距离之类的东西,保证尽可能的联通即可,所...
  • qq_35772697
  • qq_35772697
  • 2016-10-01 11:00:13
  • 396

NOIP2013 货车运输(最大生成树+LCA)

模拟考试的时候暴搜,结果写丑了,分都不分 下来啃了一下题解,发现要用到一个叫做倍增的东西,还没有学过。但是老师说的,没有那个东西,写暴力也有30~40分。。。 我觉得最大生成树还是很好理解的,因为...
  • cqbzwja
  • cqbzwja
  • 2015-08-11 21:28:58
  • 3023

NOIP2013货车运输 题解

题目描述  A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。  现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下...
  • zzx2015
  • zzx2015
  • 2015-08-11 17:59:09
  • 3110

【NOIP2013】【提高组】【Day1】【解题报告】

T1转圈游戏 题目链接:http://codevs.cn/problem/3285/ 题解:            可以发现最后的位置就是(x+m*10^k)%n;            然后...
  • sunshinezff
  • sunshinezff
  • 2015-10-26 17:51:09
  • 719

2013年noip第三题货车运输truck(树链剖分LCA+最大生成树)

写这个题的时候,其实已经手撸出LCA——tarjan算法, 下面给出一段我的LCA——tarjan模板,说真的真的很好写不能更好写了,大家可以看看别的tarjan算法再来看我的实现,个人觉得写的还不错...
  • accept_
  • accept_
  • 2016-07-07 16:32:02
  • 655

NOIP 2015 Day1T3 斗地主

暴力不解释,数据随机生成,我们可以贪心的按打出牌的数量从多到少出,那么这样就能够使最优化剪枝起到很重要的作用,怎样简化代码呢?我从题解中发现了一种将单顺子,双顺子和三顺子合成一种的方法,具体实现看代码...
  • TSOI_Vergil
  • TSOI_Vergil
  • 2016-10-17 20:52:47
  • 279

货车运输 洛谷1967 最大生成树 lca c++

题目描述A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能...
  • jpwang8
  • jpwang8
  • 2017-02-11 16:03:02
  • 279

JZOJ5475.【NOIP2017提高组】day1T3逛公园

problemDescription 策策同学特别喜欢逛公园。公园可以看成一张��个点��条边构成的有向图,且没有自环和重边。其中1号点是公园的入口,��号点是公园的出口,每条边有一个非负权值,代...
  • enjoy_pascal
  • enjoy_pascal
  • 2017-11-21 15:04:22
  • 764

【noip】【lca】火车运输 倍增

这几天把13年的提高做了,最后两道题参考了网上许多代码,最后终于改出来了,这里是day1最后一题。 描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路...
  • u011327397
  • u011327397
  • 2016-07-13 08:45:14
  • 882

【NOIP2017DAY1T3 【NOIP2017提高组正式赛】逛公园 】(拓扑序DP+分层)

Linkhttps://jzoj.net/senior/#contest/show/2180/2Problem题目大意:给定一个有向图,求从起点到终点有多少条路径代价不超过最短路代价+kSolutio...
  • Algor_pro_king_John
  • Algor_pro_king_John
  • 2017-11-18 14:34:20
  • 800
收藏助手
不良信息举报
您举报文章:NOIP 2013 提高组 Day1T3 货车运输【最大生成树】【LCA】
举报原因:
原因补充:

(最多只允许输入30个字)