1. 程式人生 > >POJ 1161 Walls(Floyd , 建圖)

POJ 1161 Walls(Floyd , 建圖)

== clas mem have 聚會 城市 define clu include

題意:

技術分享圖片

給定n個城市, 然後城市之間會有長城相連, 長城之間會圍成M個區域, 有L個vip(每個vip會處於一個城市裏)要找一個區域聚會, 問一共最少跨越多少個長城。

分析:

其實這題難就難在建圖, 因為圖中的點不再是城市, 而是城市之間長城圍成的區域, 只要把區域提取出來, 這題就是簡單的Floyd了。

我們可以把每個區域的邊先記錄下來, 然後有共邊的就是相鄰的區域, vip所在的城市都是vip的出發區域,枚舉聚會區域,然後都可能的vip區域都求一次取最少值再求和即可。

#include<iostream>
#include<vector>
#include<algorithm>
#include
<cstring> #include<cstdio> #include<cmath> #include<cstdlib> #include<ctime> #include<queue> #include<set> #include<map> #include<stack> #include<bitset> #define rep(i,a,b) for(int i = a; i < b; i++) #define _rep(i,a,b) for(int i = a; i <= b; i++) #define
mem(a,n) memset(a,n,sizeof(a)) #define fre(a) freopen(a,"r", stdin); typedef long long LL; using namespace std; int M, N, L; const int Max = 300, Max_v = 50; int viper[Max_v]; int G[Max][Max]; vector<int> city[Max][Max]; // which city have u to v; vector<int> vip_city[Max]; int close_city[300000];
int main(){ rep(i,0,Max) rep(j,0,Max) G[i][j] = (i == j ? 0 : 1e6); cin >> M >> N >> L; rep(i,0,L){ cin >> viper[i]; } _rep(i,1,M){ int p,k,cnt = 0; cin >> k; int point[Max]; rep(j,0,k){ cin >> p; rep(q,0,L) if(p == viper[q]) vip_city[viper[q]].push_back(i); //把vip可能所在的城市加入vip_city point[cnt++] = p; } rep(j,0,cnt){ int u = point[j], v = point[(j+1)%cnt];//在環上每兩個相鄰點就是一條邊 city[u][v].push_back(i); city[v][u].push_back(i); } } _rep(i,1,N){ _rep(j,1,N){ if(i != j && city[i][j].size() > 1){ int cnt = 0; rep(k,0,city[i][j].size()){ close_city[cnt++] = city[i][j][k];//如果這條邊有多於2個城市, 那麽這些城市兩兩之間都是相鄰城市 } rep(k,0,cnt){ rep(l,k+1,cnt){ int u = close_city[k], v = close_city[l]; G[u][v] = 1; G[v][u] = 1; } } } } } for(int k = 1; k <= M; k++){ for(int i = 1; i <= M; i++){ for(int j = 1; j <= M; j++){ if(G[i][k] + G[k][j] < G[i][j]){ G[i][j] = G[i][k] + G[k][j]; } } } } int ans = 1e9; _rep(pick, 1, M){//枚舉聚會區域 int t = 0; rep(i,0,L){//枚舉每個vip的可能區域 int v = viper[i]; int min_dis = 1e6; rep(j,0,vip_city[v].size()) { int in = vip_city[v][j]; min_dis = min(min_dis, G[in][pick]); } t += min_dis; } ans = min(t, ans); } cout << ans << "\n"; }

POJ 1161 Walls(Floyd , 建圖)