poj 1161 Walls
Posted Omz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }
以上是关于poj 1161 Walls的主要内容,如果未能解决你的问题,请参考以下文章