货车运输

版权声明:本文为博主原创文章,未经博主允许不得转载。

传送门:货车运输

题目描述

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。

算法:倍增,最小生成树

Solution:很明显,这道题所想要使用的路径一定是权值尽量大的。因为路径的权值越大,载重量越多。因此我们所有的货车都会在路径权值尽量大的路径上跑,可以用最小生成树反过来,也就是构造说所谓的“最大”生成树。构造树之后,我们可以保证货车按题目要求所经过的所有路径必定在这棵树上,因为这是一个路径尽量大权值的集合。然后就可以用LCA的模板,因为载重量的大小由路径上权值最小的路径权值决定,所以我们可以顺便在过程中记录一个数组下标意义与Father[i][j]相同的Dis[i][j]。表示这i到第2^j个父亲这一段路上路径的最小权值。然后就可以出解了。

Hint:

  kruskal中并查集的数组Father大小一定要开到最大边数,初始化也要初始到边数m。

  求LCA的时候返回的是路径上的最小权值每次用Ans进行比较。

  构造成树的边数只需开到2倍点数n。

  递推LCA如果像如下代码一样放在DFS外面进行递推一定要先循环j再循环i。

  1 #include<cstdio>
  2 #include<algorithm>
  3 using namespace std;
  4
  5 const int MAXN = 10001;
  6 const int MAXM = 50001;
  7 const int MAX = 15;
  8
  9 struct DATA{
 10     int u,v,Dis;
 11     bool operator < (DATA Tmp) const {return Tmp.Dis<Dis;}
 12 }Data[MAXM];
 13 int Father[MAXM];
 14 int Find(int t){
 15     return t==Father[t]?t:Father[t]=Find(Father[t]);
 16 }
 17
 18 struct EDGE{
 19     int Next,To,Dis;
 20 }Edge[MAXN<<1|1];
 21 int Head[MAXN<<1|1],Size;
 22 void Ins(int From,int To,int Dis){
 23     Edge[++Size].Next=Head[From];
 24     Head[From]=Size;
 25     Edge[Size].To=To;
 26     Edge[Size].Dis=Dis;
 27 }
 28
 29 int n,m,q;
 30 int Indgr[MAXN];
 31
 32 int Deep[MAXN],f[MAXN][MAX+1],Dis[MAXN][MAX+1];bool Vis[MAXN];
 33 void Dfs(int u){
 34     for(int i=Head[u];i;i=Edge[i].Next){
 35         int v=Edge[i].To;
 36         if(Vis[v]) continue;Vis[v]=1;
 37         Dis[v][0]=Edge[i].Dis;
 38         Deep[v]=Deep[u]+1;f[v][0]=u;
 39         Dfs(v);
 40     }
 41 }
 42
 43 void Make_Tree(){
 44     for(int i=1;i<=m;i++) Father[i]=i;
 45     sort(1+Data,1+m+Data);
 46
 47     for(int i=1;i<=m;i++){
 48         int u=Find(Data[i].u),v=Find(Data[i].v);
 49         if(u!=v){
 50             Father[u]=v;Indgr[Data[i].u]++;Indgr[Data[i].v]++;
 51             Ins(Data[i].u,Data[i].v,Data[i].Dis);
 52             Ins(Data[i].v,Data[i].u,Data[i].Dis);
 53         }
 54     }
 55
 56     for(int i=1;i<=n;i++)
 57         if(Indgr[i]<=2&&!Vis[i]){
 58             Vis[i]=1;
 59             Dfs(i);
 60         }
 61     for(int j=1;j<=MAX;j++)for(int i=1;i<=n;i++){
 62         f[i][j]=f[f[i][j-1]][j-1];
 63         Dis[i][j]=min(Dis[i][j-1],Dis[f[i][j-1]][j-1]);
 64     }
 65 }
 66
 67 int LCA(int u,int v){
 68     if(Deep[u]<Deep[v]) swap(u,v);
 69     int D_Value=Deep[u]-Deep[v],Ans=Data[1].Dis;
 70     for(int i=0;i<=MAX;i++)
 71         if(D_Value&(1<<i))
 72             {Ans=min(Ans,Dis[u][i]);u=f[u][i];}
 73     if(u==v) return Ans;
 74     for(int i=MAX;i>=0;i--)
 75         if(f[u][i]!=f[v][i]){
 76             Ans=min(min(Dis[u][i],Dis[v][i]),Ans);
 77             u=f[u][i];v=f[v][i];
 78         }
 79     return min(Ans,min(Dis[u][0],Dis[v][0]));
 80 }
 81
 82 template <typename Type> inline void Read(Type &in){
 83     Type f=1;char ch=getchar();in=0;
 84     for(;ch>‘9‘||ch<‘0‘;ch=getchar())if(ch==‘-‘)f=-1;
 85     for(;ch>=‘0‘&&ch<=‘9‘;ch=getchar())in=in*10+ch-‘0‘;in*=f;
 86 }
 87
 88 int main(){
 89     Read(n);Read(m);
 90     for(int i=1;i<=m;i++){
 91         Read(Data[i].u);Read(Data[i].v);Read(Data[i].Dis);
 92     }
 93     Make_Tree();
 94
 95     Read(q);
 96     for(int i=1,u,v;i<=q;i++){
 97         Read(u);Read(v);
 98         printf("%d\n",Find(u)!=Find(v)?-1:LCA(u,v));
 99     }
100
101     return 0;
102 }
时间: 2024-10-07 17:06:17

货车运输的相关文章

AC日记——货车运输 codevs

3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物. 输入描述 Input Description 第一行有两个用一个空格隔开的整数 n,m,表示 A

洛谷P1967 [NOIP2013提高组Day1T2]货车运输

P1967 货车运输 题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物. 输入输出格式 输入格式: 输入文件名为 truck.in. 输入文件第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道 路. 接下来 m 行每行 3 个整数 x. y. z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y

倍增LCA NOIP2013 货车运输

货车运输 题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物. 输入输出格式 输入格式: 输入文件名为 truck.in. 输入文件第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道 路. 接下来 m 行每行 3 个整数 x. y. z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条

3287 货车运输 2013年NOIP全国联赛提高组 40 分

3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物. 输入描述 Input Description 第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和

poj1330|bzoj3732|noip2013 货车运输 kruskal+倍增lca

学了一早上倍增,感觉lca还是tarjan好写. poj1330 1 #include <stdio.h> 2 #include <string.h> 3 #include <queue> 4 #include <algorithm> 5 #define DEG 20//2^20 6 #define maxn 10010 7 using namespace std; 8 struct node 9 { 10 int v, next; 11 }a[maxn*2

noip2013货车运输

P1967 货车运输 题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物. 输入输出格式 输入格式: 输入文件名为 truck.in. 输入文件第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道 路. 接下来 m 行每行 3 个整数 x. y. z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y

3287 货车运输

3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物. 输入描述 Input Description 第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城

C++之路进阶——LCA(货车运输)

3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物. 输入描述 Input Description 第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和

Codevs3278[NOIP2013]货车运输

3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物. 输入描述 Input Description 第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和