首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

poj1161 - Walls

  • 24-03-05 07:00
  • 3835
  • 6051
blog.csdn.net

                                  想看更多的解题报告: http://iyenn.com/rec/1824570.html
                                  转载请注明出处:http://blog.csdn.net/wangjian8006

题目大意:给出n个点,在这些点中有些点是俱乐部点,并且有m个区域是由点围成的
输入第一行代表n个点
第二行代表m个区域
第3行代表俱乐部有L个
第四行有L个数,分别标记哪些个点事是俱乐部
接下来2*m行,代表m个区域,每个区域由两行表示,第一行为区域由T个点围成的,
第二行T个数代表是哪些点围成这个区域,这些点按逆时针围成这个区域,相邻两点代表一条边
最后一点和第一点也是一条边,这样就是一个闭合的区域

现在问,在图中找出一个区域,使得所有俱乐部点到这个区域所要穿过的边之和最少,
输出最少的边数之和

解题思路:先建图建错了,很尴尬的重新建图,将所有区域看成点建图,然后接下来的做法可以看代码注释
写完这题已经天黑了,被这题虐了一下午。...

  1. /*
  2. floyd
  3. Memory 788K
  4. Time 63MS
  5. */
  6. #include
  7. using namespace std;
  8. #define MAXE 205
  9. #define MAXV 255
  10. #define INF INT_MAX
  11. #define min(a,b) (a>b?b:a)
  12. int n,m;
  13. int club[35],clubsum; //俱乐部情况
  14. int regsum,firstv,secondv,tmpv,tmpedge; //用来处理区域
  15. int map[MAXE][MAXE]; //首先保存区域相邻情况,然后保存最短路径
  16. int edge[MAXV][MAXV]; //看边在哪个区域,一条边只能是包含两个区域
  17. int markedge[MAXV][MAXE]; //markedge[i][j]标记i点与j区域是否相邻
  18. int ans;
  19. void floyd(){
  20. int k,i,j;
  21. for(i=0;i0; //这里注意初始化
  22. for(k=0;k
  23. for(i=0;i
  24. if(map[i][k]!=-1){
  25. for(j=0;j
  26. if(map[k][j]!=-1){
  27. //如果i到j走不通,直接赋值
  28. if(map[i][j]==-1 || map[i][k]+map[k][j]
  29. map[i][j]=map[i][k]+map[k][j];
  30. }
  31. }
  32. }
  33. int main(){
  34. #ifndef U
  35. freopen("d:\\test.in","r",stdin);
  36. #endif
  37. int i,j,k;
  38. int tmpv,tmpedge;
  39. while(~scanf("%d",&m)){
  40. scanf("%d%d",&n,&clubsum);
  41. for(i=0;iscanf("%d",&club[i]);
  42. memset(map,-1,sizeof(map));
  43. memset(markedge,0,sizeof(markedge));
  44. memset(edge,-1,sizeof(edge));
  45. for(i=0;i
  46. scanf("%d%d",®sum,&firstv);
  47. tmpv=firstv;
  48. markedge[firstv][i]=1;
  49. for(j=1;j
  50. scanf("%d",&secondv);
  51. markedge[secondv][i]=1; //标记点和区域相邻
  52. tmpedge=edge[tmpv][secondv];
  53. if(tmpedge!=-1){ //一条边只被两个区域包含
  54. map[tmpedge][i]=map[i][tmpedge]=1; //这两个区域相邻了
  55. }else{
  56. edge[tmpv][secondv]=edge[secondv][tmpv]=i;
  57. }
  58. tmpv=secondv;
  59. }
  60. tmpedge=edge[tmpv][firstv];
  61. if(tmpedge!=-1){
  62. map[tmpedge][i]=map[i][tmpedge]=1;
  63. }else{
  64. edge[tmpv][firstv]=edge[firstv][tmpv]=i;
  65. }
  66. }
  67. //得到相邻区域的图后求最短路径
  68. floyd();
  69. ans=INF;
  70. for(i=0;i
  71. int sum=0;
  72. for(j=0;j//找出和俱乐部点相邻的区域,在这些区域到i区域的一个最小值之和与答案比较
  73. tmpv=INF;
  74. for(k=0;k
  75. if(markedge[club[j]][k]){
  76. tmpv=min(tmpv,map[k][i]);
  77. }
  78. sum+=tmpv;
  79. }
  80. ans=min(ans,sum);
  81. }
  82. printf("%d\n",ans);
  83. }
  84. return 0;
  85. }


=================================================================

 

  1. /*
  2. 前面错误的代码留着做个纪念吧
  3. */
  4. #include
  5. #include
  6. using namespace std;
  7. #define MAXV 260
  8. #define MAXR 210
  9. #define INF INT_MAX
  10. #define min(a,b) (a>b?b:a)
  11. int map[MAXV][MAXV]; //存边的连通情况
  12. int ans[MAXV][MAXR]; //存点到地区最少要穿过几条线
  13. int m,n; //地区与点的总数
  14. int club[40],clubsum; //俱乐部的情况
  15. int vsum[MAXR],ver[MAXR][MAXV]; //存地区情况
  16. int flag[MAXR]; //存边界情况,flag标记地区是否为边界地区
  17. int d[MAXV][MAXV]; //从点到其他点最少经过几条边
  18. void bfs(int first){
  19. queue <int>q;
  20. bool vis[MAXV];
  21. int i,v;
  22. memset(vis,0,sizeof(vis));
  23. q.push(first);
  24. vis[first]=1;
  25. while(!q.empty()){
  26. v=q.front();q.pop();
  27. for(i=1;i<=n;i++)
  28. if(!vis[i] && map[v][i]){
  29. q.push(i);
  30. vis[i]=1;
  31. d[first][i]=d[first][v]+1;
  32. }
  33. }
  34. }
  35. int main(){
  36. #ifndef U
  37. // freopen("d:\\test.in","r",stdin);
  38. #endif
  39. int i,j,k;
  40. int key,tmp,vtmp;
  41. while(~scanf("%d",&m)){
  42. scanf("%d%d",&n,&clubsum);
  43. for(i=0;iscanf("%d",&club[i]); //输入俱乐部情况
  44. tmp=-1;
  45. memset(map,0,sizeof(map)); //输入地区情况,并且连边
  46. for(i=0;i
  47. scanf("%d%d",&vsum[i],&ver[i][0]);
  48. for(j=1;j
  49. scanf("%d",&ver[i][j]);
  50. map[ver[i][j-1]][ver[i][j]]=map[ver[i][j]][ver[i][j-1]]=1;
  51. }
  52. map[ver[i][j-1]][ver[i][0]]=map[ver[i][0]][ver[i][j-1]]=1;
  53. if(vsum[i]>tmp){tmp=vsum[i];vtmp=i;}
  54. }
  55. memset(flag,0,sizeof(flag));
  56. for(i=0;i
  57. for(j=0;j
  58. if(!flag[j]){
  59. for(k=0;k
  60. if(ver[vtmp][i]==ver[j][k]) break;
  61. }
  62. if(k1;
  63. }
  64. }
  65. memset(d,0,sizeof(d));
  66. for(i=1;i<=n;i++) bfs(i);
  67. for(i=1;i<=n;i++){
  68. for(j=0;j
  69. ans[i][j]=d[i][ver[j][0]];
  70. for(k=1;k
  71. ans[i][j]=min(ans[i][j],d[i][ver[j][k]]);
  72. }
  73. }
  74. }
  75. for(i=0;i
  76. for(j=0;j
  77. if(flag[j])
  78. ans[ver[vtmp][i]][j]=min(ans[ver[vtmp][i]][j],1);
  79. }
  80. key=INF;
  81. for(i=0;i
  82. tmp=0;
  83. for(j=0;j
  84. tmp+=ans[club[j]][i];
  85. }
  86. key=min(key,tmp);
  87. }
  88. printf("%d\n",key);
  89. }
  90. return 0;
  91. }


 

注:本文转载自blog.csdn.net的wangjian8006的文章"http://blog.csdn.net/wangjian8006/article/details/7958838"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top