P2245 星际导航
Posted driverben
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2245 星际导航相关的知识,希望对你有一定的参考价值。
题目描述
sideman 做好了回到Gliese星球的硬件准备,但是sideman的导航系统还没有完全设计好。为了方便起见,我们可以认为宇宙是一张有N 个顶点和M 条边的带权无向图,顶点表示各个星系,两个星系之间有边就表示两个星系之间可以直航,
而边权则是航行的危险程度。
sideman 现在想把危险程度降到最小,具体地来说,就是对于若干个询问(A,B),sideman 想知道从顶点A
sideman 现在想把危险程度降到最小,具体地来说,就是对于若干个询问(A,B),sideman 想知道从顶点A
航行到顶点B 所经过的最危险的边的危险程度值最小可能是多少。作为 sideman的同学,你们要帮助sideman
返回家园,兼享受安全美妙的宇宙航行。所以这个任务就交给你了。
View Code
输入输出格式
输入格式:第一行包含两个正整数N和M,表示点数和边数。
之后M行,每行三个整数A,B和L,表示顶点A和B之间有一条边长为L的边。顶点从1开始标号。
下面一行包含一个正整数Q,表示询问的数目。
之后Q行,每行两个整数 A和B,表示询问A和B之间最危险的边危险程度的可能最小值。
输出格式:对于每个询问, 在单独的一行内输出结果。如果两个顶点之间不可达, 输出impossible。
输入输出样例
输入样例#1:
4 5 1 2 5 1 3 2 2 3 11 2 4 6 3 4 4 3 2 3 1 4 1 2
输出样例#1:
5 4 5
说明
对于 40%的数据,满足 N≤1000,M≤3000,Q≤1000
对于 80%80\%80% 的数据,满足 N≤10000,M≤105,Q≤1000
对于 100%100\%100% 的数据,满足 N≤105,M≤3×105,Q≤105,L≤109,数据不保证没有重边和自环。
代码
kruskal重构树裸题,做法同货车运输
最危险的边危险程度的可能最小值,也就是最大值最小
我们边权按升序排序,val[lca(x,y)]即为答案
#include<bits/stdc++.h> using namespace std; const int maxn=200000+100,maxm=200000+100,md=20+5; int head[maxn],val[maxn],f[maxn],dep[maxn],lg[maxn]; int ff[maxn][md]; int size=0,cnt=0; struct tree { int to,next; }e[maxm<<1]; struct edge { int u,v,val; }E[maxm<<1]; int n,m; void init() { for(int i=1;i<=n;i++) f[i]=i; } int find(int x) { return f[x]==x?x:f[x]=find(f[x]); } void addedge(int u,int v) { e[++size].to=v;e[size].next=head[u];head[u]=size; } inline int read() { int x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=(x<<3)+(x<<1)+ch-‘0‘;ch=getchar();} return x*f; } bool cmp(const edge&a,const edge&b) { return a.val>b.val; } void kruskal() { for(int i=1;i<=m;i++) { int u=E[i].u,v=E[i].v; int fu=find(u),fv=find(v); if(fu!=fv) { cnt++; f[cnt]=f[fu]=f[fv]=cnt; val[cnt]=E[i].val; addedge(cnt,fu);addedge(fu,cnt); addedge(fv,cnt);addedge(cnt,fv); } } } void dfs(int u,int fa) { dep[u]=dep[fa]+1; ff[u][0]=fa; for(int i=1;i<=lg[dep[u]];i++) ff[u][i]=ff[ff[u][i-1]][i-1]; for(int i=head[u];i;i=e[i].next) { int to=e[i].to; if(to==fa)continue; dfs(to,u); } } int lca(int x,int y) { if(dep[x]<dep[y]) swap(x,y); while(dep[x]>dep[y]) x=ff[x][lg[dep[x]-dep[y]]]; if(x==y) return x; for(int i=lg[dep[x]];i>=0;i--) if(ff[x][i]!=ff[y][i])x=ff[x][i],y=ff[y][i]; return ff[x][0]; } int main() { n=read(),m=read();cnt=n; init(); for(int i=1;i<=m;i++) E[i].u=read(),E[i].v=read(),E[i].val=read(); sort(E+1,E+1+m,cmp); kruskal(); for(int i=1;i<=n;i++) lg[i]=lg[i-1]+(1<<(lg[i-1]+1)==i); for(int i=1;i<=cnt;i++) if(!dep[i]) dfs(find(i),0); int k=read(); for(int i=1;i<=k;i++) { int x=read(),y=read(); if(find(x)!=find(y))printf("-1\n"); else printf("%d\n",val[lca(x,y)]); } return 0; }
以上是关于P2245 星际导航的主要内容,如果未能解决你的问题,请参考以下文章