hdu 6115(LCA 暴力)

Factory

Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)
Total Submission(s): 367    Accepted Submission(s): 124

Problem Description

我们将A省简化为由N个城市组成,某些城市之间存在双向道路,而且A省的交通有一个特点就是任意两个城市之间都能通过道路相互到达,且在不重复经过城市的情况下任意两个城市之间的到达方案都是唯一的。聪明的你一定已经发现,这些城市构成了树这样一个结构。

现在百度陆续开了许许多多的子公司。每家子公司又会在各城市中不断兴建属于该子公司的办公室。

由于各个子公司之间经常有资源的流动,所以公司员工常常想知道,两家子公司间的最小距离。
我们可以把子公司看成一个由办公室组成的集合。那么两个子公司A和B的最小距离定义为min(dist(x,y))(x∈A,y∈B)。其中dist(x,y)表示两个办公室之间的最短路径长度。
现在共有Q个询问,每次询问分别在两个子公司间的最小距离。

Input

第一行一个正整数T,表示数据组数。
对于每组数据:
第一行两个正整数N和M。城市编号为1至N,子公司编号为1至M。
接下来N-1行给定所有道路的两端城市编号和道路长度。
接下来M行,依次按编号顺序给出各子公司办公室所在位置,每行第一个整数G,表示办公室数,接下来G个数为办公室所在位置。
接下来一个整数Q,表示询问数。
接下来Q行,每行两个正整数a,b(a不等于b),表示询问的两个子公司。
【数据范围】
0<=边权<=100
1<=N,M,Q,工厂总数<=100000

Output

对于每个询问,输出一行,表示答案。

Sample Input

1

3 3

1 2 1

2 3 1

2 1 1

2 2 3

2 1 3

3

1 2

2 3

1 3

Sample Output

1

0

0

Source

2017"百度之星"程序设计大赛 - 初赛(B)

都是暴力可以过 我知道为什么 我的就是wa  先贴上来 有空改下 这是错的代码  找不到错 好像是LCA的板子有问题

这题难道暴力不超时吗

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<map>
  5 #include<cstdlib>
  6 #include<vector>
  7 #include<set>
  8 #include<queue>
  9 #include<cstring>
 10 #include<string.h>
 11 #include<algorithm>
 12 typedef long long ll;
 13 typedef unsigned long long LL;
 14 const int INF=1e9;
 15 using namespace std;
 16 const int N=200000+100;
 17 int head[N];
 18 int cnt;
 19 int vis[N];
 20 int dis[N];
 21 vector<int>vc[N];
 22 int d[N],dp[N][30];
 23 struct node{
 24     int to,next,w;
 25 }edge[2*N];
 26 int t1;
 27 int pos[N],dep[N],f[N];
 28 void init(){
 29     for(int i=1;i<N;i++)vc[i].clear();
 30     cnt=0;
 31     memset(head,-1,sizeof(head));
 32     memset(pos,-1,sizeof(pos));
 33     memset(dis,0,sizeof(dis));
 34     t1=0;
 35 }
 36 void add(int u,int v,int w){
 37     edge[cnt].to=v;
 38     edge[cnt].w=w;
 39     edge[cnt].next=head[u];
 40     head[u]=cnt++;
 41 }
 42 void init_RMQ(int n){
 43     for(int i=1;i<=n;i++)dp[i][0]=i;
 44     for(int j=1;(1<<j)<=n;j++)
 45     for(int i=1;i+(1<<j)-1<=n;i++)
 46     if(dep[dp[i][j-1]]<dep[dp[i+(1<<j-1)][j-1]])dp[i][j]=dp[i][j-1];
 47     else
 48         dp[i][j]=dp[i+(1<<j-1)][j-1];
 49         //dp[i][j]=min(dp[i][j-1],dp[i+(1<<j-1)][j-1]);
 50 }
 51 int RMQ(int l,int r){
 52     int k=0;
 53     while((1<<k+1)<=r-l+1)k++;
 54     if(dep[dp[l][k]]<dep[dp[r-(1<<k)+1][k]])return dp[l][k];
 55     else
 56         return dp[r-(1<<k)+1][k];
 57     //return min(dep[dp[l][k]],dep[dp[r-(1<<k)+1][k]]);
 58 }
 59 int lca(int u,int v){
 60     if(pos[u]>pos[v])return f[RMQ(pos[v],pos[u])];
 61     else
 62         return f[RMQ(pos[u],pos[v])];
 63 }
 64 void DFS(int x,int deep){
 65     f[t1]=x;
 66     dep[t1]=deep;
 67     pos[x]=t1++;
 68     for(int i=head[x];i!=-1;i=edge[i].next){
 69         int v=edge[i].to;
 70         if(pos[v]==-1){
 71             dis[v]=dis[x]+edge[i].w;
 72             DFS(v,deep+1);
 73             f[t1]=x;
 74             dep[t1++]=deep;
 75         }
 76
 77     }
 78 }
 79 int main(){
 80     int t;
 81     scanf("%d",&t);
 82     while(t--){
 83         init();
 84         //memset(dis,0,sizeof(dis));
 85         int n,m;
 86         scanf("%d%d",&n,&m);
 87         for(int i=1;i<=n-1;i++){
 88             int u,v,w;
 89             scanf("%d%d%d",&u,&v,&w);
 90             add(u,v,w);
 91             add(v,u,w);
 92         }
 93         init_RMQ(3*n-1);
 94         DFS(1,0);
 95         for(int i=2;i<=n;i++){
 96             cout<<dis[i]<<endl;
 97         }
 98         for(int i=1;i<=m;i++){
 99             int tt;
100             scanf("%d",&tt);
101             for(int j=1;j<=tt;j++){
102                 int x;
103                 scanf("%d",&x);
104                 vc[i].push_back(x);
105             }
106         }
107         int q;
108         scanf("%d",&q);
109         while(q--){
110             int a,b;
111             scanf("%d%d",&a,&b);
112             int ans=INF;
113             for(int i=0;i<vc[a].size();i++)
114             for(int j=0;j<vc[b].size();j++){
115                 int u=vc[a][i];
116                 int v=vc[b][j];
117                 int tt=lca(u,v);
118                 ans=min(ans,abs(dis[u]+dis[v]-2*dis[tt]));
119             }
120             cout<<ans<<endl;
121         }
122
123     }
124
125 }
时间: 2024-10-10 14:40:10

hdu 6115(LCA 暴力)的相关文章

HDU - 6115 Factory (LCA 倍增)

题目传送门:HDU - 6115  Factory 题目大意: (中文题,简单解答下题意) 存在N个城市和M个百度的子公司,N个城市间有N-1条道路连接(一颗树),每个子公司都有办公室,办公室分布在各个城市,现在提问,两个子公司间的最小距离. 分析: 枚举提问的两个子公司的办公室间的距离,求出最短距离即可: 例如:子公司company1办公室在城市 1 2 3     子公司company2的办公室在城市5 6 ,若求company1,company2的最短距离,即枚举(1,5).(1,6).(

HDU 4912 LCA+贪心

Paths on the tree Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 531    Accepted Submission(s): 182 Problem Description bobo has a tree, whose vertices are conveniently labeled by 1,2,…,n. Th

HDU 2874 LCA离线算法

Connections between cities Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4477    Accepted Submission(s): 1284 Problem Description After World War X, a lot of cities have been seriously damage

hdu 4876(剪枝+暴力)

题意:给定n,k,l,接下来给出n个数,让你从n个数中选取k个数围成一圈,然后从这k个数中随意选出连续的m(m>=1&&m<=k)个数进行异或后得到[l,r]区间的所有值,让你求最大的r. 分析:关键问题是需要剪枝! 代码实现: #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #inclu

hdu 4499 Cannon(暴力)

题目链接:hdu 4499 Cannon 题目大意:给出一个n*m的棋盘,上面已经存在了k个棋子,给出棋子的位置,然后求能够在这种棋盘上放多少个炮,要求后放置上去的炮相互之间不能攻击. 解题思路:枚举行放的情况,用二进制数表示,每次放之前推断能否放下(会不会和已经存在的棋子冲突),放下后推断会不会互相攻击的炮,仅仅须要对每一个新加入的炮考虑左边以及上边就能够了. #include <cstdio> #include <cstring> #include <algorithm&

hdu 2586 LCA模板题(离线算法)

http://acm.hdu.edu.cn/showproblem.php?pid=2586 Problem Description There are n houses in the village and some bidirectional roads connecting them. Every day peole always like to ask like this "How far is it if I want to go from house A to house B&quo

HDU 4547 LCA倍增算法

CD操作 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 1111    Accepted Submission(s): 297 Problem Description 在Windows下我们可以通过cmd运行DOS的部分功能,其中CD是一条很有意思的命令,通过CD操作,我们可以改变当前目录. 这里我们简化一下问题,假设只有一个根目录,

【bzoj3251】树上三角形 朴素LCA+暴力

题目描述 给定一大小为n的有点权树,每次询问一对点(u,v),问是否能在u到v的简单路径上取三个点权,以这三个权值为边长构成一个三角形.同时还支持单点修改. 输入 第一行两个整数n.q表示树的点数和操作数 第二行n个整数表示n个点的点权 以下n-1行,每行2个整数a.b,表示a是b的父亲(以1为根的情况下) 以下q行,每行3个整数t.a.b 若t=0,则询问(a,b) 若t=1,则将点a的点权修改为b 输出 对每个询问输出一行表示答案,“Y”表示有解,“N”表示无解. 样例输入 5 5 1 2

HDU - 3078 Network(暴力+LCA)

题目大意:给出n个点的权值,m条边,2种操作 0 u num,将第u个点的权值改成num k u v,询问u到v这条路上第k大的权值点 解题思路:该点的话直接该,找第k大的话直接暴力 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define N 80010 #define M 160010 struct Edge{ int to, next, val; }