洛谷 P2245 星际导航 解题报告
P2245 星际导航
题目描述
sideman做好了回到Gliese 星球的硬件准备,但是sideman的导航系统还没有完全设计好。为了方便起见,我们可以认为宇宙是一张有N 个顶点和M 条边的带权无向图,顶点表示各个星系,两个星系之间有边就表示两个星系之间可以直航,而边权则是航行的危险程度。
sideman 现在想把危险程度降到最小,具体地来说,就是对于若干个询问(A, B),sideman 想知道从顶点A 航行到顶点B 所经过的最危险的边的危险程度值最小可能是多少。作为sideman 的同学,你们要帮助sideman 返回家园,兼享受安全美妙的宇宙航行。所以这个任务就交给你了。
输入输出格式
输入格式:
第一行包含两个正整数N 和M,表示点数和边数。
之后 M 行,每行三个整数A,B 和L,表示顶点A 和B 之间有一条边长为L 的边。顶点从1 开始标号。
下面一行包含一个正整数 Q,表示询问的数目。
之后 Q 行,每行两个整数A 和B,表示询问A 和B 之间最危险的边危险程度的可能最小值。
输出格式:
对于每个询问, 在单独的一行内输出结果。如果两个顶点之间不可达, 输出impossible。
说明
对于40% 的数据,满足N≤1000,M≤3000,Q≤1000。
对于 80% 的数据,满足N≤10000,M≤105,Q≤1000。
对于 100% 的数据,满足N≤105,M≤3×105,Q≤105,L≤109。数据不保证没有重边和自环。
真是的,不爱倍增了,拍了好久啊。。
思路:求最小生成树以后打树上倍增
错误点:
倍增跳到同一深度后没有判是否已经相等
堆优化的prim应该不是每次进队都加边
倍增同一深度后向上跳时应该先更新答案再跳(我居然可以错的这么蠢。。)
Code:
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int N=100010;
int head0[N],edge0[N<<1],to0[N<<1],next0[N<<1],cnt0;
void add0(int u,int v,int w)
{
edge0[++cnt0]=w;to0[cnt0]=v;next0[cnt0]=head0[u];head0[u]=cnt0;
}
int head[N],edge[N<<1],to[N<<1],next[N<<1],cnt;
void add(int u,int v,int w)
{
edge[++cnt]=w;to[cnt]=v;next[cnt]=head[u];head[u]=cnt;
}
int used[N],m,n,Q,dep[N],anc[N];
void dfs(int now,int an)
{
used[now]=1;
anc[now]=an;
for(int i=head0[now];i;i=next0[i])
{
int v=to0[i],w=edge0[i];
if(!used[v])
dfs(v,an);
}
}
void init()
{
memset(used,0,sizeof(used));
for(int i=1;i<=n;i++)
if(!used[i])
{
dfs(i,i);
add0(0,i,0);
}
}
struct node
{
int from,to,w;
bool friend operator <(node n1,node n2)
{
return n1.w>n2.w;
}
node(){}
node(int from,int to,int w)
{
this->from=from;
this->to=to;
this->w=w;
}
};
priority_queue <node > q;
void prim()
{
memset(used,0,sizeof(used));
for(int i=head0[0];i;i=next0[i])
{
int v=to0[i],w=edge0[i];
node tt(0,v,w);
q.push(tt);
}
int cntt=0;
while(!q.empty()&&cntt<n)
{
int u=q.top().to;
if(used[u]) {q.pop();continue;}
add(q.top().from,q.top().to,q.top().w);
add(q.top().to,q.top().from,q.top().w);
used[u]=1;
cntt++;
q.pop();
for(int i=head0[u];i;i=next0[i])
{
int v=to0[i],w=edge0[i];
if(!used[v])
{
node tt(u,v,w);
q.push(tt);
}
}
}
}
int f[N][21],fw[N][21];
void dfs2(int now)
{
used[now]=1;
for(int i=head[now];i;i=next[i])
{
int v=to[i],w=edge[i];
if(!used[v])
{
f[v][0]=now;
fw[v][0]=w;
dep[v]=dep[now]+1;
dfs2(v);
}
}
}
void init2()
{
memset(used,0,sizeof(used));
dfs2(0);
for(int j=1;j<=20;j++)
for(int i=0;i<=n;i++)
{
f[i][j]=f[f[i][j-1]][j-1];
fw[i][j]=max(fw[i][j-1],fw[f[i][j-1]][j-1]);
}
}
void query(int x,int y)
{
int ans=0;
if(dep[x]<dep[y]) swap(x,y);
for(int i=20;i>=0;i--)
if(dep[f[x][i]]>=dep[y])
{
ans=max(ans,fw[x][i]);
x=f[x][i];
}
for(int i=20;i>=0;i--)
if(f[x][i]!=f[y][i])
{
ans=max(ans,max(fw[x][i],fw[y][i]));
x=f[x][i],y=f[y][i];
}
if(x!=y)
ans=max(ans,max(fw[x][0],fw[y][0]));
printf("%d\n",ans);
}
int main()
{
freopen("data.out","r",stdin);
freopen("bf.out","w",stdout);
scanf("%d%d",&n,&m);
int u,v,w;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w);
add0(u,v,w),add0(v,u,w);
}
init();
prim();
init2();
scanf("%d",&Q);
for(int i=1;i<=Q;i++)
{
scanf("%d%d",&u,&v);
if(anc[u]!=anc[v])
printf("impossible\n");
else
query(u,v);
}
return 0;
}
2018.6.30
洛谷 P2245 星际导航 解题报告的更多相关文章
- [洛谷P2245]星际导航
题目大意:有一张n点m边的带权无向图,和一些问题,每次询问两个点之间的路径的最大边权最小是多少. 解题思路:同NOIP2013货车运输,只是数据增大,大变成小,小变成大了而已.所以具体思路见货车运输. ...
- 洛谷 P1783 海滩防御 解题报告
P1783 海滩防御 题目描述 WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和仓库总是被敌方派人偷袭 ...
- 洛谷 P4597 序列sequence 解题报告
P4597 序列sequence 题目背景 原题\(\tt{cf13c}\)数据加强版 题目描述 给定一个序列,每次操作可以把某个数\(+1\)或\(-1\).要求把序列变成非降数列.而且要求修改后的 ...
- 洛谷1087 FBI树 解题报告
洛谷1087 FBI树 本题地址:http://www.luogu.org/problem/show?pid=1087 题目描述 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全 ...
- 洛谷 P3349 [ZJOI2016]小星星 解题报告
P3349 [ZJOI2016]小星星 题目描述 小\(Y\)是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有\(n\)颗小星星,用\(m\)条彩色的细线串了起来,每条细线连着两颗小星星. 有一 ...
- 洛谷 P3177 树上染色 解题报告
P3177 [HAOI2015]树上染色 题目描述 有一棵点数为\(N\)的树,树边有边权.给你一个在\(0\) ~ \(N\)之内的正整数\(K\),你要在这棵树中选择\(K\)个点,将其染成黑色, ...
- 洛谷 P4705 玩游戏 解题报告
P4705 玩游戏 题意:给长为\(n\)的\(\{a_i\}\)和长为\(m\)的\(\{b_i\}\),设 \[ f(x)=\sum_{k\ge 0}\sum_{i=1}^n\sum_{j=1}^ ...
- 洛谷 P1272 重建道路 解题报告
P1272 重建道路 题目描述 一场可怕的地震后,人们用\(N\)个牲口棚\((1≤N≤150\),编号\(1..N\))重建了农夫\(John\)的牧场.由于人们没有时间建设多余的道路,所以现在从一 ...
- 洛谷 [HNOI2014]道路堵塞 解题报告
[HNOI2014]道路堵塞 题意 给一个有向图并给出一个这个图的一个\(1\sim n\)最短路,求删去这条最短路上任何一条边后的最短路. 又事SPFA玄学... 有个结论,新的最短路一定是\(1\ ...
随机推荐
- ccf201703-2学生排队
问题描述 体育老师小明要将自己班上的学生按顺序排队.他首先让学生按学号从小到大的顺序排成一排,学号小的排在前面,然后进行多次调整.一次调整小明可能让一位同学出队,向前或者向后移动一段距离后再插入队列. ...
- 在win10下使用docker快速搭建ruby开发环境
docker在windows下发力的时候必将取代各种虚拟机,并改变程序员的开发习惯,或许还会改变infra的工作. 概要: 在Windows下搭建开发环境一直是infra(我)头疼的事情.为了解决这个 ...
- 2017-2018-1 20155202 张旭 嵌入式C语言——时钟提取时分秒
2017-2018-1 20155202 张旭 嵌入式C语言--时钟提取时分秒 任务要求: 在作业本上完成附图作业,要认真看题目要求. 提交作业截图 作弊本学期成绩清零(有雷同的,不管是给别人传答案, ...
- python 井字棋(Tic Tac Toe)
说明 用python实现了井字棋,整个框架是本人自己构思的,自认为比较满意.另外,90%+的代码也是本人逐字逐句敲的. minimax算法还没完全理解,所以参考了这里的代码,并作了修改. 特点 可以选 ...
- 阿里云centos系统中配置mysql,并远程连接到本地的navicat
1.直接使用yum命令下载mysql5.6来进行安装是不能成功的,安装过程会有问题,这里我们需要使用rpm命令来先进下载.下载路径为:http://dev.mysql.com/get/mysql-co ...
- harbor使用和管理
一.上传本地镜像到harbor中 先在harbor 中创建testdocker 项目 因为我们本地没有镜像,我们先拉取一个镜像,然后进行下面的操作 查看nginx 镜像 2.下载nginx镜像到本地 ...
- allegro 基本步骤
PCB 1.建立电路板 首先是打开PCB编辑器——开始--所有程序-- Allegro SPB 15.5--PCB Editor,在弹出的对话框中选择Allegro PCB Design 610(PC ...
- 转 git config命令使用
. git config简介 我们知道config是配置的意思,那么git config命令就是对git进行一些配置.而配置一般都是写在配置文件里面,那么git的配置文件在哪里呢?互动一下,先问下大家 ...
- Git多人协作工作流程
前言 之前一直把Git当做个人版本控制的工具使用,现在由于工作需要,需要多人协作维护文档,所以去简单了解了下Git多人协作的工作流程,发现还真的很多讲解的,而且大神也已经讲解得很清楚了,这里就做一个简 ...
- 微软职位内部推荐-Senior Software Engineer - Back End
微软近期Open的职位: SharePoint is a multi-billion dollar enterprise business that has grown from an on-prem ...