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 }
时间: 2024-08-01 06:31:08

3287 货车运输 2013年NOIP全国联赛提高组 40 分的相关文章

3285 转圈游戏 2013年NOIP全国联赛提高组

3285 转圈游戏 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description n 个小伙伴(编号从 0 到 n-1)围坐一圈玩游戏.按照顺时针方向给 n 个位置编号,从0 到 n-1.最初,第 0 号小伙伴在第 0 号位置,第 1 号小伙伴在第 1 号位置,……,依此类推.游戏规则如下:每一轮第 0 号位置上的小伙伴顺时针走到第 m 号位置,第 1 号位置小伙伴走到第 m+1 号位置,……,依此类推

Codevs 3286 火柴排队 2013年NOIP全国联赛提高组 树状数组,逆序对

题目:http://codevs.cn/problem/3286/ 3286 火柴排队  2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度.现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为:,其中 ai表示第一列火柴中第 i 个火柴的高度,bi表示第二列火柴中第 i 个火柴的高度.每列火柴中相

积木大赛 2013年NOIP全国联赛提高组

题目描述 Description 春春幼儿园举办了一年一度的"积木大赛".今年比赛的内容是搭建一座宽度为 n 的大厦,大厦可以看成由 n 块宽度为1的积木组成,第i块积木的最终高度需要是hi.在搭建开始之前,没有任何积木(可以看成 n 块高度为 0 的积木).接下来每次操作,小朋友们可以选择一段连续区间[L,R],然后将第 L 块到第 R 块之间(含第 L 块和第 R 块)所有积木的高度分别增加1.小 M 是个聪明的小朋友,她很快想出了建造大厦的最佳策略,使得建造所需的操作次数最少.但

洛谷 P1980 记数问题 2013年NOIP全国联赛普及组

3291 记数问题 2013年NOIP全国联赛普及组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解题目描述 Description试计算在区间1到n的所有整数中,数字x(0≤x≤9)共出现了多少次?例如,在1到11中,即在1.2.3.4.5.6.7.8.9.10.11中,数字1出现了4次. 输入描述 Input Description输入共1行,包含2个整数n.x,之间用一个空格隔开. 输出描述 Output Description输出共1行,包含一个整

codevs 1044 拦截导弹 1999年NOIP全国联赛提高组

1044 拦截导弹 1999年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹. 输入描述 Input Description 输入导弹

贪心 + 并查集 之 CODE[VS] 1069 关押罪犯 2010年NOIP全国联赛提高组

/* 贪心 + 并查集 之 CODE[VS] 1069 关押罪犯  2010年NOIP全国联赛提高组 两座监狱,M组罪犯冲突,目标:第一个冲突事件的影响力最小. 依据冲突大小,将M组罪犯按从大到小排序,按照排序结果,依次把每组罪犯分开放入两个监狱, 直到当前这组罪犯已经在同一个监狱中了,此时即为答案. 实现: 1)通过不在同一个监狱的罪犯,推断出在同一个监狱的罪犯.(依据:一共就两个监狱)      ftr[b] = a+n   // a和b是在不同监狱 ftr[c] = a+n   // a和

1058 合唱队形 2004年NOIP全国联赛提高组

1058 合唱队形 2004年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形. 合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2-,K,他们的身高分别为T1,T2,-,TK,  则他们的身高满足T1<...<Ti>Ti+1>->TK(1<=i<=K). 你的任务是,已知所

codevs 1199 开车旅行 2012年NOIP全国联赛提高组

1199 开车旅行 2012年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 小A 和小B决定利用假期外出旅行,他们将想去的城市从1到N 编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i的海拔高度为Hi,城市 i 和城市 j 之间的距离 d[i,j]恰好是这两个城市海拔高度之差的绝对值,即d[i, j] = |Hi − Hj|. 旅行过程中,小A 和小B轮流开

1154 能量项链 2006年NOIP全国联赛提高组 codevs

1154 能量项链  2006年NOIP全国联赛提高组 codevs 题目描述 Description 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠子,前一颗珠子的尾标记一定等于后一颗珠子的头标记.因为只有这样,通过吸盘(吸盘是Mars人吸收能量的一种器官)的作用,这两颗珠子才能聚合成一颗珠子,同时释放出可以被吸盘吸收的能量.如果前一颗能量珠的头标记为m,尾标记为r,后一颗能量