[luogu 1967]货车运输
Posted kakakakakaka
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[luogu 1967]货车运输相关的知识,希望对你有一定的参考价值。
货车运输
题目描述
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。
输入输出样例
4 3 1 2 4 2 3 3 3 1 1 3 1 3 1 4 1 3
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。
题解:
求最大生成树,然后在最大生成树上跑LCA。
因为是最大生成树,所以这样得到的路径最小值必定是题目所要求的答案。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 using namespace std; 8 int n,m,l,ans[30001],lim; 9 int father[10001]; 10 struct node{int from,to,dis;}map[50001]; 11 int find(int x){if(father[x]==x)return x;else return father[x]=find(father[x]);} 12 bool cmp(const node a,const node b){return a.dis>b.dis;} 13 struct question{int s,t,id;}que[60001]; 14 int head[10001],size=1; 15 struct Node{int next,to,dis;}edge[100005]; 16 void putin(int from,int to,int dis){size++;edge[size].dis=dis;edge[size].to=to;edge[size].next=head[from];head[from]=size;} 17 int fa[10001][15],mmin[10001][15],vis[10001],dep[10001]; 18 void dfs(int r,int depth) 19 { 20 vis[r]=1; 21 dep[r]=depth; 22 for(int i=head[r];i!=-1;i=edge[i].next) 23 { 24 int y=edge[i].to; 25 if(!vis[y]) 26 { 27 fa[y][0]=r; 28 mmin[y][0]=edge[i].dis; 29 dfs(y,depth+1); 30 } 31 } 32 } 33 void RMQ() 34 { 35 for(int i=1;i<=lim;i++) 36 for(int j=1;j<=n;j++) 37 { 38 fa[j][i]=fa[fa[j][i-1]][i-1]; 39 mmin[j][i]=min(mmin[j][i-1],mmin[fa[j][i-1]][i-1]); 40 } 41 } 42 int LCA(int x,int y) 43 { 44 int i,j,ans=2000000000; 45 if(dep[x]<dep[y])swap(x,y); 46 for(i=lim;i>=0;i--) 47 if(dep[x]-(1<<i)>=dep[y]) 48 { 49 ans=min(ans,mmin[x][i]); 50 x=fa[x][i]; 51 } 52 if(x!=y) 53 { 54 for(i=lim;i>=0;i--) 55 { 56 if(fa[x][i]!=fa[y][i]) 57 { 58 ans=min(ans,min(mmin[x][i],mmin[y][i])); 59 x=fa[x][i]; 60 y=fa[y][i]; 61 } 62 } 63 ans=min(ans,min(mmin[x][0],mmin[y][0])); 64 x=fa[x][0]; 65 y=fa[y][0]; 66 } 67 return ans; 68 } 69 int main() 70 { 71 int i,j; 72 memset(head,-1,sizeof(head)); 73 memset(ans,-1,sizeof(ans)); 74 memset(mmin,127/3,sizeof(mmin)); 75 scanf("%d%d",&n,&m);lim=log2(n); 76 for(i=1; i<=n; i++)father[i]=i; 77 for(i=1; i<=m; i++)scanf("%d%d%d",&map[i].from,&map[i].to,&map[i].dis); 78 sort(map+1,map+m+1,cmp); 79 for(i=1; i<=m; i++) 80 { 81 int p=find(map[i].from),q=find(map[i].to); 82 if(p!=q) 83 { 84 father[p]=q; 85 putin(p,q,map[i].dis); 86 putin(q,p,map[i].dis); 87 } 88 } 89 scanf("%d",&l); 90 for(i=1;i<=n;i++)if(father[i]==i)dfs(i,0); 91 RMQ(); 92 for(i=1; i<=l; i++) 93 { 94 int from,to; 95 scanf("%d%d",&from,&to); 96 if(find(from)==find(to))printf("%d\n",LCA(from,to)); 97 else printf("-1\n"); 98 } 99 return 0; 100 }
以上是关于[luogu 1967]货车运输的主要内容,如果未能解决你的问题,请参考以下文章