POJ 1161 Walls【floyd 以面为点建图】
题目链接:http://poj.org/problem?id=1161
题目大意:
1.给出m个区域,n个俱乐部点。接下来是n个俱乐部点以及各个区域由什么点围成。求一个区域到各个俱乐部点的距离之和最小。
解题思路:
1.这题建图比较麻烦,以区域为点建图,区域之间若有边,则两区域的距离为1,建完图后跑一遍floyd就可以求出两两区域的最小距离。
2.对于答案,枚举每一个区域到各个俱乐部点的相邻区域的距离之和,取最小值。
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #define mem(a, b) memset(a, b, sizeof(a)) 5 using namespace std; 6 const int inf = 0x3f3f3f3f; 7 8 int m, n, l; 9 int club[35], vis[260][210];//标记i点是否与j区域相邻 10 int edge[260][260]; //更新i到j边的相邻区域是哪个 11 int map[260][260]; //建图 12 13 void floyd() 14 { 15 for(int i = 1; i <= m; i ++) 16 map[i][i] = 0; 17 for(int k = 1; k <= m; k ++) 18 for(int i = 1; i <= m; i ++) 19 for(int j = 1; j <= m; j ++) 20 map[i][j] = map[j][i] = min(map[i][j], map[i][k] + map[k][j]); 21 } 22 23 int main() 24 { 25 while(scanf("%d", &m) != EOF) //m个区域 26 { 27 mem(edge, -1); //表示没有相邻区域 28 mem(map, inf), mem(vis, -1); 29 scanf("%d%d", &n, &l);//n个点,其中l个点是俱乐部所在的点 30 for(int i = 1; i <= l; i ++) 31 scanf("%d", &club[i]); 32 for(int i = 1; i <= m; i ++) 33 { 34 int k, temp; 35 scanf("%d", &k); //每个区域由k个点逆时针围成 注意最后一个点与第一个点也有边 36 scanf("%d", &temp); 37 vis[temp][i] = 1; 38 int first = temp; 39 for(int j = 1; j < k; j ++) 40 { 41 int x; 42 scanf("%d", &x); 43 vis[x][i] = 1; 44 if(edge[temp][x] == -1 || edge[x][temp] == -1) 45 edge[temp][x] = edge[x][temp] = i; 46 else 47 { 48 map[edge[temp][x]][i] = map[i][edge[temp][x]] = 1; 49 edge[temp][x] = edge[x][temp] = i; 50 } 51 temp = x; 52 } 53 if(edge[first][temp] == -1 || edge[temp][first] == -1) 54 edge[first][temp] = edge[temp][first] = i; 55 else 56 { 57 map[edge[first][temp]][i] = map[i][edge[first][temp]] = 1; 58 edge[first][temp] = edge[temp][first] = i; 59 } 60 } 61 floyd(); 62 int ans = inf; 63 for(int i = 1; i <= m; i ++) //枚举答案 枚举每一个区域 64 { 65 int temp = 0; 66 for(int j = 1; j <= l; j ++) 67 { 68 int temp1 = inf; 69 for(int k = 1; k <= m; k ++) 70 { 71 if(vis[club[j]][k] == -1) 72 continue; 73 temp1 = min(temp1, map[i][k]); 74 } 75 temp += temp1; 76 } 77 ans = min(ans, temp); 78 } 79 printf("%d\n", ans); 80 } 81 return 0; 82 }