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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 座城市和 m 条道路。
接下来 m 行每行 3 个整数 x、y、z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条限重为 z 的道路。注意:x 不等于 y,两座城市之间可能有多条道路。
接下来一行有一个整数 q,表示有 q 辆货车需要运货。
接下来 q 行,每行两个整数 x、y,之间用一个空格隔开,表示一辆货车需要从 x 城市运输货物到 y 城市,注意:x 不等于 y。

输出描述 Output Description

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

样例输入 Sample Input

4 3
1 2 4
2 3 3
3 1 1
3
1 3
1 4
1 3

样例输出 Sample Output

3
-1
3

数据范围及提示 Data Size & Hint

对于 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。

分类标签 Tags

 

I am Fade

I am a mengbier

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<cmath>
  6 using namespace std;
  7 const int MAXN= 50001;
  8 struct node
  9 {
 10     int u;
 11     int v;
 12     int w;
 13     int nxt;
 14 }edge[MAXN];
 15 int head[MAXN];
 16 int num=1;
 17 int numm;
 18 int n,m,q;
 19 int f[MAXN];
 20 int anc[30001][300],len[30001][300],dep[30001];
 21 int maxnb;
 22 int que[MAXN];
 23 int vis[MAXN];
 24 void BFSforLCA(int o)
 25 {
 26     memset(vis,0,sizeof(vis));
 27     memset(que,0,sizeof(que));
 28     int i;
 29     int h=0,t=1;
 30     que[0]=o;
 31     vis[o]=1;
 32     len[o][0]=0x7fff;
 33     for(;h<t;h++)
 34     {
 35         int u=que[h];
 36         for(int j=head[u];j!=-1;j=edge[j].nxt)
 37         {
 38             int v=edge[j].v;int w=edge[j].w;
 39             if(vis[v]==1)continue;
 40             vis[v]=1;    que[t]=v;    t++;
 41             anc[v][0]=u;    len[v][0]=w;    dep[v]=dep[u]+1;
 42         }
 43     }
 44 }
 45 void InitializtionForLCA()
 46 {
 47     for(int j=0;(1<<j)<n;j++)
 48     {    for(int i=0;i<=n;i++)
 49         {
 50             anc[i][j+1]=anc[anc[i][j]][j];
 51             len[i][j+1]=min(len[anc[i][j]][j],len[i][j]);
 52         }
 53         maxnb=j;}    
 54 }
 55 int LCA(int u,int v)
 56 {
 57     int i,j;
 58     if(dep[u]<dep[v])swap(u,v);
 59     int ans=0x7fffff;
 60     //cout<<dep[u]<<"**"<<dep[v]<<endl;
 61     for(int i=maxnb;i>=0;i--)
 62     {
 63         int p=anc[u][i];
 64         if(dep[anc[u][i]]>=dep[v])
 65         {
 66             //cout<<dep[anc[u][i]]<<"  "<<dep[v]<<endl;
 67             ans=min(ans,len[u][i]);
 68             u=anc[u][i];
 69         }
 70     }
 71     for(int i=maxnb;i>=0;i--)
 72     {
 73         if(anc[u][i]!=anc[v][i])
 74         {
 75             ans=min(ans,min(len[u][i],len[v][i]));
 76             u=anc[u][i];v=anc[v][i];
 77         }
 78     }
 79     if(u!=v)
 80     {
 81         ans=min(ans,min(len[u][0],len[v][0]));
 82         u=anc[u][0];v=anc[v][0];
 83     }
 84     return ans;
 85 }
 86 
 87 int comp(const node & a,const node & b)
 88 {return a.w>b.w;}
 89 int find(int x)
 90 {if(f[x]!=x)return f[x]=find(f[x]);return f[x];}
 91 int unionn(int x,int y)
 92 {int fx=find(x);int fy=find(y);f[fx]=fy;}
 93 
 94 void Kruskal()
 95 {
 96     sort(edge+1,edge+num,comp);
 97     numm=num;//储存边的个数,把最大生成树存到edge上 
 98     int k=0;
 99     for(int i=1;i<=numm;i++)
100     {
101         if(find(edge[i].u)!=find(edge[i].v))
102         {
103             k++;
104             unionn(edge[i].u,edge[i].v);
105             edge[num].u=edge[i].u;edge[num].v=edge[i].v;edge[num].w=edge[i].w;
106             edge[num].nxt=head[edge[num].u];
107             head[edge[num].u]=num++;
108             edge[num].u=edge[num-1].v;edge[num].v=edge[num-1].u;edge[num].w=edge[num-1].w;
109             edge[num].nxt=head[edge[num].u];
110             head[edge[num].u]=num++;
111             //edge[numm+edge[i].u].u=edge[i].u;edge[num+edge[i].u].v=edge[i].v;edge[num+edge[i].u++].w=edge[i].w;
112         }
113         if(k==n-1)break;
114     }
115 }
116 int main()
117 {
118     scanf("%d%d",&n,&m);
119     for(int i=1;i<=n;i++)head[i]=-1,f[i]=i;
120     for(int i=1;i<=m;i++)
121     {
122         cin>>edge[num].u>>edge[num].v>>edge[num].w;num++;
123     }
124     Kruskal();
125     for(int i=1;i<=n;i++)
126     //if(vis[i])
127     BFSforLCA(i);
128     InitializtionForLCA();// 初始化父子关系 
129     /*for(int i=1;i<=n;i++)
130     cout<<anc[i][0]<<" ";
131     cout<<endl<<"*******************"<<endl;
132     for(int i=1;i<=n;i++)
133         for(int j=head[i];j!=-1;j=edge[j].nxt)
134         cout<<edge[j].u<<"->"<<edge[j].v<<endl;
135     */
136     scanf("%d",&q);
137     int x,y;
138     for(int i=1;i<=q;i++)
139     {
140         scanf("%d%d",&x,&y);
141         int p=LCA(x,y);
142         if(find(x)!=find(y))
143         printf("-1\n");
144         else printf("%d\n",p);
145     }
146     return 0;
147 }

 

 

以上是关于3287 货车运输 2013年NOIP全国联赛提高组 40 分的主要内容,如果未能解决你的问题,请参考以下文章

Codevs 3287 货车运输

[Codevs] 3287 货车运输

AC日记——货车运输 codevs

CODEVS 3287NOIP2013火车运输

[NOIP2013提高组]货车运输

[NOIP2013]货车运输