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

货车运输

时间:2017-02-09 23:38:01      阅读:185      评论:0      收藏:0      [点我收藏+]

标签:char   城市   意义   include   lca   amp   生成树   ble   space   

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

传送门:货车运输

题目描述

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 }

 

货车运输

标签:char   城市   意义   include   lca   amp   生成树   ble   space   

原文地址:http://www.cnblogs.com/Never-See/p/6384141.html

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