\(\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。

代码

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<cstdio>
  4. #include<cstdlib>
  5. #include<cstring>
  6. #include<cmath>
  7. //include STL queue
  8. #include<queue>
  9. //include STL set
  10. #include<set>
  11. //include STL pair
  12. #include<utility>
  13. #define N 5005
  14. #define M 25005
  15. using namespace std;
  16. struct pos{
  17. int x,dis;
  18. int step;
  19. }tmp,fro;
  20. struct Edge{
  21. int nxt,to,w;
  22. }e[M<<1];
  23. int n,m,tot=1,head[N],a[N];
  24. queue<pos>q;
  25. set<pair<int,int> >cnt;
  26. void addedge(int x,int y,int z)
  27. {
  28. e[++tot]=(Edge){head[x],y,z},head[x]=tot;//顺时针
  29. e[++tot]=(Edge){head[y],x,-z},head[y]=tot;//逆时针
  30. }
  31. int getdis(int x,int y)//返回两地经度差
  32. {
  33. int z=min(abs(x-y),360-abs(x-y));
  34. if((x+z)%360==y)
  35. return z;//顺时针
  36. else
  37. return -z;//逆时针
  38. }
  39. int bfs()
  40. {
  41. fro.x=1;fro.dis=0,fro.step=0;
  42. q.push(fro);
  43. while(!q.empty())
  44. {
  45. fro=q.front(),q.pop();
  46. int x=fro.x,dis=fro.dis,step=fro.step;
  47. cnt.insert(make_pair(x,dis));
  48. for(int i=head[x],y;i;i=e[i].nxt)
  49. {
  50. y=e[i].to;
  51. if(y==1 && dis+e[i].w)
  52. return step+1;
  53. if(cnt.find(make_pair(y,dis+e[i].w))!=cnt.end())
  54. continue;
  55. tmp.x=y,tmp.dis=dis+e[i].w,tmp.step=step+1;
  56. q.push(tmp);
  57. }
  58. }
  59. return -1;
  60. }
  61. int main()
  62. {
  63. scanf("%d%d",&n,&m);
  64. for(int i=1;i<=n;i++)
  65. scanf("%d",a+i);
  66. for(int i=1,x,y,z;i<=m;i++){
  67. scanf("%d%d",&x,&y);
  68. z=getdis(a[x],a[y]);
  69. if(z>0) addedge(x,y,z);//顺时针
  70. else addedge(y,x,-z);//逆时针
  71. }
  72. printf("%d\n",bfs());
  73. return 0;
  74. }
  75. /*
  76. 3 3
  77. 0
  78. 120
  79. 240
  80. 1 2
  81. 2 3
  82. 1 3
  83. */

完结撒花

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. 基于COCA词频表的文本词汇分布测试工具v0.2

    update: 简单整理了一下代码的组织. 处理的单词封装成类,单词的修正,信息的显示都作为其内的方法. 写得还比较糙,工具本身可以封装,还有对于单词的变形基本没什么处理,以后有时间再改. 项目托管到 ...

  2. P4279 [SHOI2008]小约翰的游戏(Anti_nim)

    Link 题面 题目描述 小约翰经常和他的哥哥玩一个非常有趣的游戏:桌子上有 \(n\) 堆石子,小约翰和他的哥哥轮流取石子,每个人取的时候,可以随意选择一堆石子, 在这堆石子中取走任意多的石子,但不 ...

  3. es使用--新建、删除、增删改数据

    # 进入bin目录 cd /czz/elsearch/bin # 后台启动(不加-d参数则是前台启动,日志在控制台) # 后台启动日志如果不配置,在es目录的logs下面 ./elasticsearc ...

  4. 安装Node,创建vue项目,运行及打包

    1.安装node js 下载地址:http://nodejs.cn/download/ 2.安装完成后运行Node.js command prompt(node -v查看安装版本) 3.安装npm(由 ...

  5. 扫描仪扫描文件处理-Photoshop批处理无响应问题

    问题描述:Photoshop批处理时候卡死.卡住.无响应问题(出现在处理60M及以上TIFF文件的时候) 解决办法: 调整系统虚拟内存见<扫描-Photoshop批处理内存不足问题解决> ...

  6. 最大子段和之M子段和

    最大M子段和 题目模型 N个整数组成的序列 \(a_1,a_2,a_3,-,a_n\) ,将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的. 问题分析 方法一: 看到序列,我们首先要尝试 ...

  7. logstash 过滤filter

    logstash过滤器插件filter详解及实例   1.logstash过滤器插件filter 1.1.grok正则捕获 grok是一个十分强大的logstash filter插件,他可以通过正则解 ...

  8. selenium--数据填充

    from time import sleep from selenium import webdriver br = webdriver.Chrome() url = "https://ww ...

  9. pycharm2018.3.5 下载激活(windows平台)

    软件下载: 百度网盘下载 提取码: 73p7 激活操作: 1.下载jar包 JetbrainsCrack-4.2-release-enc.jar 链接:https://pan.baidu.com/s/ ...

  10. Solr6.4.2异常:org.apache.solr.common.SolrException: Error opening new searcher

    版权声明:本文为博主原创文章,转载请附上原文出处链接和本声明. 原文链接:https://www.cnblogs.com/chenghu/p/13840021.html Solr版本6.4.2 启动S ...