\(\mathbf{POJ\;2432}\)题解

题意

给出圆上的\(N\)个点,每个点有一个经度(大于\(0\)小于\(360\));再给出\(M\)条双向边,保证边\(x y\)仅会沿圆上较短的弧连接,且不存在边连接圆上相对的两个点的情况。

求一条从点\(1\)出发最后回到点\(1\),且能环绕圆的经过点数最少的路径。

思路

边权为\(1\)的最短路,显然可以想到BFS。但由于还要满足“能环绕圆”这一条件,我们需要加一些限制。

不妨预处理出每条边的连接的两地间的经度差作为边权,顺时针边置正权,逆时针边置负权,并在BFS的状态中加入一维,表示路径权值和。

那么在BFS时,就可以用已走过的路径权值和\(dis\)来判断一条从\(1\)出发再回到\(1\)的路径是否合法了。

不难发现,若\(dis\)不为\(0\),那么一条从\(1\)出发回到\(1\)的路径一定是合法的,反之亦然。

另外,一个状态\(f(x,dis)\)一定不会出现两次,所以用一个集合(STL set)来记录已经出现过的状态,起一般BFS中标记数组的作用。

最后,在计算答案时用一个成员变量\(step\)记录经过了几个点。

使用以上算法即可通过本题。如果想进一步优化,可以把queue改为手写queue,set改为手写Hash。

代码

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
//include STL queue
#include<queue>
//include STL set
#include<set>
//include STL pair
#include<utility>
#define N 5005
#define M 25005
using namespace std;
struct pos{
int x,dis;
int step;
}tmp,fro;
struct Edge{
int nxt,to,w;
}e[M<<1];
int n,m,tot=1,head[N],a[N];
queue<pos>q;
set<pair<int,int> >cnt;
void addedge(int x,int y,int z)
{
e[++tot]=(Edge){head[x],y,z},head[x]=tot;//顺时针
e[++tot]=(Edge){head[y],x,-z},head[y]=tot;//逆时针
}
int getdis(int x,int y)//返回两地经度差
{
int z=min(abs(x-y),360-abs(x-y));
if((x+z)%360==y)
return z;//顺时针
else
return -z;//逆时针
}
int bfs()
{
fro.x=1;fro.dis=0,fro.step=0;
q.push(fro);
while(!q.empty())
{
fro=q.front(),q.pop();
int x=fro.x,dis=fro.dis,step=fro.step;
cnt.insert(make_pair(x,dis));
for(int i=head[x],y;i;i=e[i].nxt)
{
y=e[i].to;
if(y==1 && dis+e[i].w)
return step+1;
if(cnt.find(make_pair(y,dis+e[i].w))!=cnt.end())
continue;
tmp.x=y,tmp.dis=dis+e[i].w,tmp.step=step+1;
q.push(tmp);
}
}
return -1;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",a+i);
for(int i=1,x,y,z;i<=m;i++){
scanf("%d%d",&x,&y);
z=getdis(a[x],a[y]);
if(z>0) addedge(x,y,z);//顺时针
else addedge(y,x,-z);//逆时针
}
printf("%d\n",bfs());
return 0;
}
/*
3 3
0
120
240
1 2
2 3
1 3
*/

完结撒花

POJ 2432的更多相关文章

  1. poj 2432 Around the world bfs+哈希

    由于每个点的状态包含走过来的距离,所以要存二维的状态,但是状态总量太多,所以可以用哈希来搞. 那么就是bfs最短路,哈希记录状态了. #include <iostream> #includ ...

  2. poj和hdu部分基础算法分类及难度排序

    最近想从头开始刷点基础些的题,正好有个网站有关于各大oj的题目分类(http://www.pythontip.com/acm/problemCategory),所以写了点脚本把hdu和poj的一些题目 ...

  3. POJ 3370. Halloween treats 抽屉原理 / 鸽巢原理

    Halloween treats Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7644   Accepted: 2798 ...

  4. POJ 2356. Find a multiple 抽屉原理 / 鸽巢原理

    Find a multiple Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7192   Accepted: 3138   ...

  5. POJ 2965. The Pilots Brothers' refrigerator 枚举or爆搜or分治

    The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22286 ...

  6. POJ 1753. Flip Game 枚举or爆搜+位压缩,或者高斯消元法

    Flip Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 37427   Accepted: 16288 Descr ...

  7. POJ 3254. Corn Fields 状态压缩DP (入门级)

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9806   Accepted: 5185 Descr ...

  8. POJ 2739. Sum of Consecutive Prime Numbers

    Sum of Consecutive Prime Numbers Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 20050 ...

  9. POJ 2255. Tree Recovery

    Tree Recovery Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11939   Accepted: 7493 De ...

随机推荐

  1. Go 数组&切片

    数组相关 在Go语言中,数组是一种容器相关的数据类型,用于存放多种相同类型的数据. 数组定义 在定义数组时,必须定义数组的类型以及长度,数组一经定义不可进行改变. 同时,数组的长度是按照元素个数进行统 ...

  2. SpringBoot2.3中@Async实现异步

    启动加上@EnableAsync ,需要执行异步方法上加入@Async. 在方法上加上@Async之后 底层使用多线程技术. 不使用异步 先关代码: package com.yiyang.myfirs ...

  3. Vue路由Hash模式分析

    Vue路由Hash模式分析 Vue-router是Vue的核心组件,主要是作为Vue的路由管理器,Vue-router默认hash模式,即使用URL的Hash来模拟一个完整的URL,当URL改变时页面 ...

  4. CAS 原子操作

    理会CAS和CAS: 有时候面试官面试问你的时候,会问,谈谈你对CAS的理解,这时应该有很多人,就会比较懵,当然,我也会比较懵,当然我和很多人的懵不同,很多人可能,并不知道CAS是一个什么东西,而在我 ...

  5. DIV垂直滚动效果源码

    <div id="demo" style="width: 300; overflow: hidden; line-height:24px; height: 100p ...

  6. P2832 行路难

    题面 Link 题目背景 小X来到了山区,领略山林之乐.在他乐以忘忧之时,他突然发现,开学迫在眉睫 题目描述 山区有 \(n\) 座山.山之间有 \(m\) 条羊肠小道,每条连接两座山,只能单向通过, ...

  7. Python 自动化测试全攻略:五种自动化测试模型实战详解

    随着移动互联网的发展,软件研发模型逐步完善,软件交付质量越来越受到软件公司的重视,软件测试技术特别是自动化测试技术开始在软件系统研发过程中发挥着越来越重要的作用. 与传统的手工测试技术相比,自动化测试 ...

  8. 2020武汉dotNET俱乐部分享交流活动正式启动

    去年9月去上海参加了2019 .NET开发者峰会,感触良多.回来后便一直想着在武汉也组织一场这样的活动,推动一下武汉.NET的发展.由于疫情的影响,这个想法一直被搁浅,好在疫情总算是控制住了,所以我们 ...

  9. 版本控制系统之基于httpd搭建私有git仓库

    在上一篇博客中,我们主要聊到了git的基本工作原理和一些常用的git命令的使用:回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13787701.html:今天我 ...

  10. 每日一题 LeetCode 486. 预测赢家 【递推】【前缀和】【动态规划】

    题目链接 https://leetcode-cn.com/problems/predict-the-winner/ 题目说明 题解 主要方法:递推:动态规划:前缀和 解释说明: 求前缀和 pre_nu ...