经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » 编程经验 » 查看文章
【P1078】 文化之旅 bfs题解 - cheng-qing
来源:cnblogs  作者:cheng-qing  时间:2018/9/25 19:12:58  对本文有异议

一道数据十分水的题目,出自2012年的普及组。各种玄学算法都能过,最常见的是倒着搜的dfs。

我是在水最短路的时候刷到这个题的,因为喜欢用bfs,所以写了这个题解。

思路来自:洛谷dalao   lushangyin的题解

这个题的数据很小,n只有100,直接使用二维数组保存数据  

 也很像前向星的存边方法

定义

        a[x][i].to表示点x的第i条边所到达的点

        a[x][i].dis表示这条边的权值

        mapp[i][j]表示文化 与文化 之间的关系

        c[i]表示点 i 所有的文化

        vis[i][j]判断点 i 与点 j 之间文化目前状态

        cnt[i] 表示点i 已经有几条边了

  1. #include<bits/stdc++.h> //大家不要学
  2. using namespace std;
  3. struct gjc{//仅出自个人习惯
  4. int to;
  5. int dis;
  6. } a[110][110];
  7. int cnt[110];
  8. int n,m,k,str,en;
  9. int c[110],d[110];
  10. int mapp[110][110];
  11. int vis[2001][101];
  12. void read(){//初始化
  13. cin>>n>>k>>m>>str>>en;
  14. for(int i=1;i<=n;i++)
  15. cin>>c[i];
  16. for(int i=1;i<=k;i++)
  17. for(int j=1;j<=k;j++)
  18. cin>>mapp[i][j];
  19. for(int i=1;i<=m;i++)
  20. {
  21. int x,y,z;
  22. cin>>x>>y>>z;
  23. cnt[x]++;cnt[y]++;//边数加一
  24. a[x][cnt[x]].to=y;a[x][cnt[x]].dis=z;//希望能理解
  25. a[y][cnt[y]].to=x;a[y][cnt[y]].dis=z;
  26. }
  27. }
  28. void out()//输出
  29. {
  30. if(d[en]==0) cout<<"-1";
  31. else cout<<d[en];
  32. }
  33.  
  34. void bfs(){//不用解释
  35. priority_queue<int,vector<int>,greater<int> > que;//定义一个小根堆优化的优先队列 后来发现普通的队列好像也可以
  36. int node;
  37. node=str;
  38. que.push(node);//将起点推入队列
  39. for(int i=1;i<=n;i++)
  40. if(mapp[c[i]][c[str]]==1) vis[str][i]=1;
  41. else if(c[i]==c[str])vis[str][i]=1;//改变文化状态 根据题目大意很好理解
  42. while(!que.empty())
  43. {
  44. int v=que.top();que.pop();//取出队首元素(是一个点)
  45. for(int i=1;i<=cnt[v];i++)//遍历这个点的所有边
  46. {
  47. node=a[v][i].to;//node存储下一个点的编号
  48. if(vis[v][node]!=0) continue;//如果当前点和目标点文化有冲突就跳过
  49. if(d[node]>a[v][i].dis+d[v]||d[node]==0)//如果这么走更短或是第一次走
  50. {
  51. for(int j=1;j<=n;j++)//和上面对起点文化的改变很像
  52. {
  53. if(mapp[c[j]][c[node]==1]) vis[node][j]=1;
  54. else
  55. if(vis[v][j]==1) vis[node][j]=1;//理解一下
  56. else
  57. if(c[j]==c[node]) vis[node][j]=1;
  58. }
  59. d[node]=d[v]+a[v][i].dis;
  60. que.push(node);//将缩短路径的点推入队列中
  61. }
  62. }
  63. }
  64. }
  65.  
  66.  
  67. int main(){
  68. read();
  69. bfs();
  70. out();
  71. return 0;
  72. }

  

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号