POJ2432 Around the world
题意描述
在一个圆上有 \(n\) 点,其中有 \(m\) 条双向边连接它们,每条双向边连接两点总是沿着圆的最小弧连接。
求从 \(1\) 号点出发并回到 \(1\) 号点的一条路径,在满足并非原路返回的情况下满足经过路线数量最小。
如果不存在这样的路径输出 \(-1\)。
算法分析
本来好好的一道 BFS 被我想的辣么复杂...。
如果是单向边就是一遍 BFS 的事,但是这里是双向边又不能原路返回...。
首先考虑特殊建边:
对于 \(edge(u,v)\),求出两者的距离 \(w=dis(u,v)\)。
如果 \(u\to v\) 是顺时针走建立 \(edge(u,v,w),edge(v,u,-w)\)。
否则建立 \(edge(v,u,w),edge(u,v,-w)\)。
然后 BFS 的同时计算走过的边权之和,只要到达 \(1\) 号点时边权之和 \(\neq 0\) 即可。
判重本来是用 \(bool\) 判的,然后喜得 MLE,所以乖乖用 set 了。
当然为了减小常数,dalao 都是直接用 Hash。(蒟蒻我懒...)
没了。
代码实现
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<queue>
#include<set>
#define N 5010
#define M 25010
using namespace std;
int n,m,a[N],head[N],cnt=0;
struct Edge{
int nxt,to,val;
}ed[M<<1];
struct node{
int u,dis,step;
};
queue<node>q;
set<pair<int,int> >s;
int read(){
int x=0,f=1;char c=getchar();
while(c<'0' || c>'9') f=(c=='-')?-1:1,c=getchar();
while(c>='0' && c<='9') x=x*10+c-48,c=getchar();
return x*f;
}
int get_dis(int u,int v){
int w=min(abs(u-v),360-abs(u-v));
if((u+w)%360==v) return w;
return -w;
}
void add(int u,int v,int w){
ed[++cnt]=(Edge){head[u],v,w},head[u]=cnt;
ed[++cnt]=(Edge){head[v],u,-w},head[v]=cnt;
return;
}
int bfs(){
q.push((node){1,0,0});
while(!q.empty()){
node now=q.front();q.pop();
int u=now.u,dis=now.dis,step=now.step;
s.insert(make_pair(u,dis));
for(int i=head[u];i;i=ed[i].nxt){
int v=ed[i].to,w=ed[i].val;
if(v==1 && dis+w) return step+1;
if(s.find(make_pair(v,dis+w))!=s.end()) continue;
//set 提供 find 这个成员函数,如果其中没有这个值将返回 s.end()。
q.push((node){v,dis+w,step+1});
}
}
return -1;
}
int main(){
n=read(),m=read();
for(int i=1;i<=n;i++)
a[i]=read();
for(int i=1;i<=m;i++){//特殊建边。
int u=read(),v=read();
int w=get_dis(a[u],a[v]);
if(w>0) add(u,v,w);
else add(v,u,-w);
}
printf("%d\n",bfs());
return 0;
}
完结撒花
POJ2432 Around the world的更多相关文章
随机推荐
- Java学习day02
day02-课堂笔记 1.打开DOS命令窗口,执行java HelloWorld,执行原理? * java.exe命令会启动JVM * JVM启动之后会启动类加载器ClassLoader * Clas ...
- spring-boot-route(七)整合jdbcTemplate操作数据库
在一部分内容中,我们学习了Restful接口的编写,及接口文档的生成.我们需要将接口数据进行持久化存储,这一部分我们主要学习几种持久化框架将数据进行存储.本部分内容中,我们都将使用mysql为例来做为 ...
- 01 学习人工智能,不做笔记?做笔记不知道如何输入数学公式?“onenote+Mathematics Add-In”拯救你!onenote安装数学输入公式插件Microsoft Mathematics Add-In for Word and OneNote教程走一波
一.Microsoft Mathematics Add-In 插件下载 Microsoft Mathematics Add-In for Word and OneNote插件下载链接: https:/ ...
- 第一次面试linux后台岗位
今天给大家分享前段时间面试linux后台的面试题目,我从里面挑了几道大家比较陌生的题目,而且要那种手写代码的题目,这方面肯定很多人在实际面试时最怕的题目! 1.请说出如何用tcp服务实现文件的断点续传 ...
- 关于.netMVC 出现@ViewBag 出现错误(波浪红线)的解决方法
解决vs2015.vs2013解决mvc5 viewbag问题 1.关闭vs2015或者vs2013 打开我的电脑或者文件夹 2.打开我的电脑 在地址栏输入 %UserProfile%\AppData ...
- MeteoInfoLab脚本示例:Hamawari-8 netCDF data
示例数据:ftp://ftp.bom.gov.au/anon/sample/catalogue/Satellite/IDE00220.201507140300.nc 该数据的分辨率很高(22000*2 ...
- 【传递闭包】HDU 2157 How many ways??
UPD:现在才发现本题是个传递闭包 题目内容 春天到了,HDU校园里开满了花,姹紫嫣红,非常美丽. 葱头是个爱花的人,看着校花校草竞相开放,漫步校园,心情也变得舒畅. 为了多看看这迷人的校园,葱头决定 ...
- swoft实现自动重启服务 转
目的:1.上传代码后HTTP服务自动重启,不需要自己手动执行:php bin/swoft http:start2.自动重启适用于开发调试阶段,因为不能再后台运行所以在线上环境的话还是要重启http服务 ...
- java 实体对象转Map公共类
java 实体对象转Map公共类 package org.kxtkx.portal.utils; import java.lang.reflect.Field; import java.util.Ha ...
- Linux命令之date +%F
date命令显示当前日期 date +%F显示当前日期 [10:02:52 root@C8[ 2020-06-16DIR]#touch `hostname`_`date +%F`.log [10:03 ...