poj 1161 Walls

https://vjudge.net/problem/POJ-1161

题意:
有m个区域,n个小镇,有c个人在这些小镇中,他们要去某一个区域中聚会,从一个区域到另一个区域需要穿墙,问这些人聚到一起最少需要穿过几道墙。
题中给出的区域是用小镇描述的,某几个小镇围成一个区域,每一个区域按照顺时针方向给出的。
思路:
首先用两个vector,一个描述一个区域,属性是这个区域的边界有哪些点,另一个描述一个点,属性是这些点属于哪个区域。然后接下来,我们把每一个区域看成一个点,开始建图。
这题的难点就在于怎么建图,首先我们把一个区域看成一个点,那么怎么才能知道两个区域相邻呢?由于描述每个区域的点是以顺时针方向给出的,所以对于每个区域,当我们把每个区域的店push_back完之后,再把这个区域的点push_back进去,那么就相当于这些点构成了一个环,对于相邻的两点,如果说vis[点j][点j+1]没有东西的话,那么这个的值就等于这个区域,如果有值的话,那么就说明保存的值与当前的区域是相邻的,就把距离赋值为1,泽阳就把建图的问题解决了。
之后就是求任意两个区域的最短距离,用到了floyd算法,这倒是一个新姿势,不过很简单,就是把两点之间的距离通过图上的每一个点松弛。

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <vector>
 4 #include <algorithm>
 5 using namespace std;
 6
 7 const int inf = 0x3f3f3f3f;
 8
 9 vector<int> r[400],t[400];
10 int club[40];
11 int g[400][400];
12 int vis[400][400];
13
14 int main()
15 {
16     int m,n,c;
17
18     memset(r,0,sizeof(r));
19     memset(t,0,sizeof(t));
20
21     scanf("%d%d%d",&m,&n,&c);
22
23     memset(g,inf,sizeof(g));
24
25     for (int i = 1;i <= 399;i++) g[i][i] = 0;
26
27     for (int i = 0;i < c;i++) scanf("%d",&club[i]);
28
29     for (int i = 1;i <= m;i++)
30     {
31         int o;
32
33         scanf("%d",&o);
34
35         for (int j = 0;j < o;j++)
36         {
37             int oo;
38
39             scanf("%d",&oo);
40
41             r[i].push_back(oo);
42
43             t[oo].push_back(i);
44         }
45
46         r[i].push_back(r[i][0]);
47     }
48
49     for (int i = 1;i <= m;i++)
50     {
51         for (int j = 0;j < r[i].size() - 1;j++)
52         {
53             int fr = r[i][j],to = r[i][j+1];
54
55             if (vis[fr][to]) g[vis[fr][to]][i] = g[i][vis[fr][to]] = 1;
56             else vis[fr][to] = vis[to][fr] = i;
57         }
58     }
59
60
61
62     for (int i = 1;i <= m;i++)
63         for (int j = 1;j <= m;j++)
64         for (int k = 1;k <= m;k++)
65     {
66         if (g[j][k] > g[j][i] + g[i][k])
67             g[j][k] = g[j][i] + g[i][k];
68     }
69
70     int ans = inf;
71
72     for (int i = 1;i <= m;i++)
73     {
74         int sum = 0;
75
76         for (int j = 0;j < c;j++)
77         {
78             int minn = inf;
79
80             int cc = club[j];
81
82             for (int k = 0;k < t[cc].size();k++)
83             {
84                 int w = t[cc][k];
85
86                 minn = min(minn,g[w][i]);
87             }
88
89             sum += minn;
90         }
91
92         ans = min(ans,sum);
93     }
94
95     printf("%d\n",ans);
96
97     return 0;
98 }
时间: 2024-08-10 17:18:37

poj 1161 Walls的相关文章

POJ 1161 Walls(最短路+枚举)

POJ 1161 Walls(最短路+枚举) 题目背景 题目大意:题意是说有 n个小镇,他们两两之间可能存在一些墙(不是每两个都有),把整个二维平面分成多个区域,当然这些区域都是一些封闭的多边形(除了最外面的一个),现在,如果某几个小镇上的人想要聚会,为选择哪个区域为聚会地点,可以使他们所有人总共需要穿过的墙数最小,题目上有说明,不在某个点上聚会(聚会点在某个多边形内部),行进过程中不穿过图中的点(也就是除出发点外的其他小镇). 输入第1行代表m(2<=M<=200)个区域 第2行代表n(3&

POJ 1161 Walls【floyd 以面为点建图】

题目链接:http://poj.org/problem?id=1161 题目大意: 1.给出m个区域,n个俱乐部点.接下来是n个俱乐部点以及各个区域由什么点围成.求一个区域到各个俱乐部点的距离之和最小. 解题思路: 1.这题建图比较麻烦,以区域为点建图,区域之间若有边,则两区域的距离为1,建完图后跑一遍floyd就可以求出两两区域的最小距离. 2.对于答案,枚举每一个区域到各个俱乐部点的相邻区域的距离之和,取最小值. 1 #include<stdio.h> 2 #include<stri

POJ 1161 Walls ( Floyd &amp;&amp; 建图 )

题意 :  在某国,城市之间建起了长城,每一条长城连接两座城市.每条长城互不相交.因此,从一个区域到另一个区域,需要经过一些城镇或者穿过一些长城.任意两个城市A和B之间最多只有一条长城,一端在A城市,另一端在B城市.从A走到B,可以只在一个区域内行走,或者只在长城上行走. 有一个俱乐部,它的会员分布在不同的城市中,每个城市要么只有一个会员,要么没有会员.会员们决定要集中到一个区域内聚会.他们骑车前往目的地.首先,由于城市内交通太堵,他们不想进入任何一个城市内,其次,他们希望穿越尽可能少的长城.他

POJ 1161 Walls(Floyd , 建图)

题意: 给定n个城市, 然后城市之间会有长城相连, 长城之间会围成M个区域, 有L个vip(每个vip会处于一个城市里)要找一个区域聚会, 问一共最少跨越多少个长城. 分析: 其实这题难就难在建图, 因为图中的点不再是城市, 而是城市之间长城围成的区域, 只要把区域提取出来, 这题就是简单的Floyd了. 我们可以把每个区域的边先记录下来, 然后有共边的就是相邻的区域, vip所在的城市都是vip的出发区域,枚举聚会区域,然后都可能的vip区域都求一次取最少值再求和即可. #include<io

POJ 3470 Walls(线段树+扫描线)

[题目链接] http://poj.org/problem?id=3470 [题目大意] 给出几面墙,均垂直于x轴或者y轴,给出一些鸟的位置(二维坐标点), 鸟只会垂直x轴或者y轴飞行,并且会撞上最近的墙,问每面墙最后会有几只鸟撞上去. [题解] 我们将所有的二维坐标离散,对xy方向分别进行扫描线, 以y轴方向为例,我们先从y最小的线开始扫, 如果是墙,那么在线段树中更新其在x轴上的分布位置 如果是鸟的坐标,那么在线段树中查找其位置,更新其答案. 之后从y最大的开始反向扫描,更新,x方向也同理.

Floyd 求最短路(poj 1161)

题目:Walls 题意:给定一个图,求其中几个点相连最少要穿越的边数. 思路:这题的图要重新建,不能用原图,新图是这样的:将一个圈化为点,之间的关系是两个圈是否有公共边,然后就是求最短路问题了: #include <iostream> #include <algorithm> #include <stdlib.h> #include <time.h> #include <cmath> #include <cstdio> #includ

poj 1161 Floyd+枚举

题意是: 给出n个点,围成m个区域.从区域到另一个区域间需穿过至少一条边(若两区域相邻)——边连接着两点. 给出这么一幅图,并给出一些点,问从这些点到同一个区域的穿过边数最小值. 解题思路如下: 将区域按1~m编号,d[i][j]表示第 i 个区域到第 j 个区域的最短距离,跑一遍Floye算法O(m^3)后,枚举选择的区域,找出其中穿过边数最小值即可. 建图:题目对于每个区域的描述方式为以顺时针方向给出围成区域的点.由此可知区域由哪些边组成.易知,每条边能且只能令两个区域相邻,则用二维数组记录

图论 500题——主要为hdu/poj/zoj

转自——http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并查集======================================[HDU]1213   How Many Tables   基础并查集★1272   小希的迷宫   基础并查集★1325&&poj1308  Is It A Tree?   基础并查集★1856   More i

图论常用算法之一 POJ图论题集【转载】

POJ图论分类[转] 一个很不错的图论分类,非常感谢原版的作者!!!在这里分享给大家,爱好图论的ACMer不寂寞了... (很抱歉没有找到此题集整理的原创作者,感谢知情的朋友给个原创链接) POJ:http://poj.org/ 1062* 昂贵的聘礼 枚举等级限制+dijkstra 1087* A Plug for UNIX 2分匹配 1094 Sorting It All Out floyd 或 拓扑 1112* Team Them Up! 2分图染色+DP 1125 Stockbroker