倍增LCA NOIP2013 货车运输

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了倍增LCA NOIP2013 货车运输相关的知识,希望对你有一定的参考价值。

货车运输

题目描述

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。

 

NOIP2013,kidding me?

出个模板题???

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 using namespace std;
  6 int n,m,q;
  7 struct data{
  8     int s,e,d;
  9 }edge[50010];
 10 int f[10010];
 11 struct dt{
 12     int next,to,dis;
 13 }eg[20010];
 14 int cnt;
 15 int head[10010],deep[10010],fa[10010][32],w[10010][32];
 16 bool cmp(const data&a,const data&b){
 17     return a.d>b.d;//!
 18 }
 19 int find(int x){
 20     if(x!=f[x]) return f[x]=find(f[x]);//!
 21     return f[x];//!
 22 }
 23 void add(int start,int end,int dd){
 24     eg[++cnt].next=head[start];
 25     eg[cnt].to=end;
 26     eg[cnt].dis=dd;
 27     head[start]=cnt;
 28 }
 29 void build(){
 30     int ct=0;
 31     for(int i=1;i<=m;i++){
 32         int f1=find(edge[i].s);
 33         int f2=find(edge[i].e);
 34         if(f1!=f2){
 35             f[f1]=f2;
 36             add(edge[i].s,edge[i].e,edge[i].d);
 37             add(edge[i].e,edge[i].s,edge[i].d);
 38             ct++;
 39         }
 40         if(ct==n-1) break;
 41     }
 42 }
 43 void dfs(int u){
 44     for(int i=head[u];i;i=eg[i].next)
 45         if(!deep[eg[i].to]){
 46             deep[eg[i].to]=deep[u]+1;
 47             fa[eg[i].to][0]=u;
 48             w[eg[i].to][0]=eg[i].dis;
 49             dfs(eg[i].to);
 50         }
 51 }
 52 void work(){
 53     for(int j=1;(1<<j)<=n;j++)
 54         for(int i=1;i<=n;i++)
 55             if(fa[i][j-1]!=-1){
 56                 fa[i][j]=fa[fa[i][j-1]][j-1];
 57                 w[i][j]=min(w[i][j-1],w[fa[i][j-1]][j-1]);
 58             }
 59 }
 60 int lca(int x,int y){
 61     int rt=0x3f3f3f3f;
 62     if(deep[x]<deep[y]) swap(x,y);
 63     int i=0;
 64     for(i=0;(1<<i)<=deep[x];i++);
 65     i--;
 66     for(int j=i;j>=0;j--)
 67         if(deep[x]-(1<<j)>=deep[y]){
 68             rt=min(rt,w[x][j]);
 69             x=fa[x][j];
 70         }
 71     if(x==y) return rt;//!
 72     for(int j=i;j>=0;j--)
 73         if(fa[x][j]!=-1&&fa[x][j]!=fa[y][j]){
 74             rt=min(rt,min(w[x][j],w[y][j]));
 75             x=fa[x][j];
 76             y=fa[y][j];
 77         }
 78     return min(rt,min(w[x][0],w[y][0]));
 79 }
 80 int main(){
 81     scanf("%d%d",&n,&m);
 82     for(int i=1;i<=m;i++) scanf("%d%d%d",&edge[i].s,&edge[i].e,&edge[i].d);
 83     sort(edge+1,edge+m+1,cmp);
 84     for(int i=1;i<=n;i++) f[i]=i;
 85     build();
 86     memset(fa,-1,sizeof(fa));
 87     deep[1]=1;
 88     dfs(1);
 89     work();
 90     scanf("%d",&q);
 91     int ss=0,ee=0;
 92     for(int i=1;i<=q;i++){
 93         scanf("%d%d",&ss,&ee);
 94         if(find(ss)!=find(ee)){
 95             printf("-1\n");
 96             continue;
 97         }
 98         printf("%d\n",lca(ss,ee));
 99     }
100     return 0;
101 }

 

以上是关于倍增LCA NOIP2013 货车运输的主要内容,如果未能解决你的问题,请参考以下文章

noip2013day1t3货车运输(瓶颈路,树上倍增)

luogu1967noip2013 货车运输 [生成树kruskal LCA ]

链剖-进阶ing-填坑-NOIP2013-货车运输

洛谷 1967 NOIP2013 货车运输

P1967 [NOIP2013 提高组] 货车运输

noip-2013 货车运输