货车运输  (truck.cpp/c/pas) 

【问题描述】  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。 

【数据说明】 

对于30%的数据,0<𝑛<1,000,0<𝑚<10,000,0<𝑞<1,000;

对于60%的数据,0<𝑛<1,000,0<𝑚<50,000,0<𝑞<1,000;

对于100%的数据,0<𝑛<10,000,0<𝑚<50,000,0<𝑞<30,000,0≤z≤100,000。

 

  这道题算是我当时学习LCA tarjan离线算法的初始题了 老师拿这道题虐当年的我真的好意思吗?

  今天复习LCA算法写一写这道题的解题报告。

  首先跑一道最大生成树 为什么要跑最大生成树我现在也忘记了啊对不起我又没说人话了

  然后针对题目的询问,找寻两个点的树上距离【说是树上距离其实是两个数的树上距离的最小值,类似于网络流的容量

  然后输出这两个的树上距离就好了

  贴代码,我也不知道当年的我写出了什么神奇的代码,不过能AC就是了

  1 //先跑一遍最大生成树,然后求两个点的树上距离
  2 //或许会用到倍增?
  3 #include <algorithm>
  4 #include <iostream>
  5 #include <fstream>
  6 #include <cstdlib>
  7 #include <cstring>
  8 #include <cmath>
  9 using namespace std;
 10 ifstream fin("truck.in");
 11 ofstream fout("truck.out");
 12 struct qxx
 13 {
 14  int nw;
 15  int nxt;
 16  int pay;
 17 };
 18 qxx tree[70005];//生成树
 19 struct bin
 20 {
 21  int x;
 22  int y;
 23  int v;//从x到y点有一条边权为v的边 
 24 };
 25 bin tu[100005];//单向边 
 26 int head[10005]={0},pa[10005][20]={0}/*倍增*/,pa1[10005]={0}/*kru用*/;
 27 int pa2[10050]={0}/*tar用*/,least[10005][20]={0};
 28 int Cs[10050]={0},top=0;
 29 int dians=0,bians=0,hcs=0,bian=0;
 30 int tw[20]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288};
 31 int zhan[10050]={0};
 32 bool bj[10005]={0};//被检查过的点即为true 
 33 int ask[30005][3]={0};//询问,从ask[i][0]到ask[i][1],
 34 //在tarjan后ask[i][3]为最近公共祖先,ST后为答案
 35 int find_K(int x);//查找x所在集合的祖先
 36 int find_T(int x);//查找x所在集合的祖先
 37 void heb_K(int x,int y);//
 38 void heb_T(int x,int y);// 合并x和y集合
 39 void add(int fr,int to,int spend);//
 40 void kru();//克鲁斯卡尔
 41 void DFS(int nw);//
 42 void tarjan(int nw);//最近公共祖先 
 43 void beiz(int cs);//
 44 void ST(int bh);//
 45 bool px(bin A,bin B);//
 46 int Cz(int bh,int nw,int b);//
 47 int main(void)
 48 {
 49  fin>>dians>>bians;
 50  memset(least,127/2,sizeof(least));
 51  int a=0,b=0,c=0;
 52  for(int i=1;i<=bians;i++)
 53     {
 54      fin>>a>>b>>c;
 55      tu[i].x=a;
 56      tu[i].y=b;
 57      tu[i].v=c;
 58     }
 59  sort(tu+1,tu+bians+1,px);
 60  kru();//最大生成树
 61  Cs[1]=1;
 62  DFS(1);//默认1号节点为根 
 63  pa[1][0]=1;
 64  beiz(1);
 65  fin>>hcs;
 66  for(int i=1;i<=hcs;i++)
 67     {
 68      fin>>ask[i][0]>>ask[i][1];
 69     }
 70  tarjan(1);
 71  for(int i=1;i<=hcs;i++)
 72     {
 73      if(ask[i][2]==0)
 74        {
 75         fout<<"-1\n";
 76         continue;
 77        }
 78      memset(zhan,0,sizeof(zhan));
 79      top=0;
 80      ST(i);
 81      fout<<ask[i][2]<<"\n";
 82     }
 83  return 0;
 84 }
 85 
 86 bool px(bin A,bin B)
 87 {
 88  if(A.v>B.v)return 1;
 89  return 0;
 90 }
 91 
 92 int find_K(int x)
 93 {
 94  if(pa1[x]==0)
 95  {
 96  pa1[x]=x;
 97  return x;
 98  }
 99  if(pa1[x]==x)return x;
100  else pa1[x]=find_K(pa1[x]);
101  return pa1[x];
102 }
103 
104 int find_T(int x)
105 {
106  if(pa2[x]==0)
107    {
108    pa2[x]=x;
109    return x;
110    }
111  if(pa2[x]==x)return x;
112  int a=x;
113  while(pa2[a]!=a)a=pa2[a];
114  return a;
115 }
116 
117 void add(int fr,int to,int spend)
118 {
119  tree[++bian].nw=to;
120  tree[bian].nxt=head[fr];
121  tree[bian].pay=spend;
122  head[fr]=bian;
123  tree[++bian].nw=fr;
124  tree[bian].nxt=head[to];
125  tree[bian].pay=spend;
126  return;
127 }
128 
129 void heb_K(int x,int y)
130 {
131  int Px=0,Py=0;
132  Px=find_K(x);
133  Py=find_K(y);
134  pa1[Py]=Px;
135  return;
136 }
137 
138 void heb_T(int x,int y)
139 {
140  int Px=0,Py=0;
141  Px=find_T(x);
142  Py=find_T(y);
143  pa2[Py]=Px;
144  return;
145 }
146 
147 void DFS(int nw)
148 {
149  int child=0;
150  for(int i=head[nw];i>0;i=tree[i].nxt)
151     {
152      child=tree[i].nw;
153      if(pa[nw][0]==child)continue;
154      pa[child][0]=nw;
155      Cs[child]=Cs[nw]+1;
156      least[child][0]=tree[i].pay;
157      DFS(child);
158     }
159  return;
160 }
161 
162 void beiz(int cs)
163 {
164  if(cs>=18)return;
165  for(int i=1;i<=dians;i++)
166     {
167      pa[i][cs]=pa[pa[i][cs-1]][cs-1];
168      least[i][cs]=min(least[pa[i][cs-1]][cs-1],least[i][cs-1]);
169     }
170  beiz(cs+1);
171  return;
172 }
173 
174 void kru()
175 {
176  int Px=0,Py=0,xq=0;
177  for(int i=1;i<=bians;i++)
178     {
179      if(xq==dians-1)break;
180      Px=find_K(tu[i].x);
181      Py=find_K(tu[i].y);
182      if(Px==Py)continue;
183      xq++;
184      heb_K(tu[i].x,tu[i].y);
185      add(tu[i].x,tu[i].y,tu[i].v);
186      add(tu[i].y,tu[i].x,tu[i].v);
187     }
188  return;
189 }
190 
191 void tarjan(int nw)
192 {
193  pa2[nw]=nw;
194  int child=0;
195  for(int i=head[nw];i>0;i=tree[i].nxt)
196     {
197      child=tree[i].nw;
198      if(child==pa[nw][0])continue;
199      tarjan(child);
200      heb_T(nw,child);
201     }
202  bj[nw]=true;
203  for(int i=1;i<=hcs;i++)
204     {
205      if(ask[i][0]==nw)
206        {
207         if(bj[ask[i][1]])ask[i][2]=find_T(ask[i][1]);
208        }
209      if(ask[i][1]==nw)
210        {
211         if(bj[ask[i][0]])ask[i][2]=find_T(ask[i][0]);
212        }
213     }
214  return;
215 }
216 
217 void ST(int bh)
218 {
219  
220  int S1=abs(Cs[ask[bh][0]]-Cs[ask[bh][2]]);
221  int S2=abs(Cs[ask[bh][1]]-Cs[ask[bh][2]]);
222  
223  double K1=log((double)S1)/log((double)2);
224  double K2=log((double)S2)/log((double)2);
225  
226  int k1=(int)K1;
227  int k2=(int)K2;
228  
229  int As1=least[ask[bh][0]][k1];
230  int As2=least[Cz(bh,ask[bh][0],tw[k1])][k1];
231  int As3=0;
232  
233  if(As2<As1)As1=As2;
234  if(ask[bh][0]==ask[bh][2])As1=0x7fffffff;
235  
236  memset(zhan,0,sizeof(zhan));
237  top=0;
238  As2=least[ask[bh][1]][k2];
239  As3=least[Cz(bh,ask[bh][1],tw[k2])][k2];
240 
241  if(As3<As2)As2=As3;
242  if(ask[bh][1]==ask[bh][2])As2=0x7fffffff;
243  
244  ask[bh][2]=min(As1,As2);
245 }
246 
247 int Cz(int bh,int nw,int b)
248 {
249  zhan[++top]=nw;
250  if(nw==ask[bh][2])
251    {
252     return zhan[top-b];
253    }
254  return Cz(bh,pa[nw][0],b);
255 }

 

 posted on 2015-09-11 15:59  SakuLeaF  阅读(384)  评论(2编辑  收藏  举报