FLODY 算法的应用POJ1161

http://poj.org/problem?id=1161

解题步骤:

1.建图

2.求出每一块相邻区域并赋予距离为1;

3.利用flody算法算出任意两块区域的距离;

4.枚举每一块区域去求出要穿越的城墙数,最后取最小的即可。

程序如下:

/* 题意是:有几个人要聚会,他们在不同的城市,现在要你求出穿过最少的城墙数,不能穿越城市。 本题可以用flody算法,要先求相邻的区域,相邻的区域的值为1,然后在用flody算法算出任意两块区域的值, 最后在枚举目的城市算出最少需求穿越的城墙数 */ #include<iostream> #include<vector> #include<algorithm> using namespace std; #define inf 100000000 #define MAXM 210 #define MAXN 260 vector<int> v[MAXN];//每个城市所属的区域 int gg[MAXM][MAXM], mem[MAXN]; int N, M, L; struct REG//每个区域的信息 { int n; vector<int> ps; void input(int k) { int i, j; // vector<int> ps; ps.clear(); scanf("%d", &n); for(i=0; i<n; i++) { scanf("%d", &j); ps.push_back(j); v[j].push_back(k); } } }re[MAXM]; void getread()//读取数据 { int i; scanf("%d%d", &N, &L); for(i=0; i<=N; i++) v[i].clear(); for(i=0; i<L; i++) scanf("%d", &mem[i]); for(i=0; i<M; i++) { re[i].input(i); } } int IsNear(REG a, REG b)//判断这两个区域是否相邻 { int i, j; for(i=0; i<a.n; i++) for(j=0; j<b.n; j++) if(a.ps[i] == b.ps[j]) { int x1 = (i+1)%a.n, y1 = (j+1)%b.n; int x2 = (i-1+a.n)%a.n, y2 = (j-1+b.n)%b.n; if(a.ps[x1] == b.ps[y1] || a.ps[x1] == b.ps[y2] || a.ps[x2] == b.ps[y1] || a.ps[x2] == b.ps[y2]) return 1; } return 0; } void build() { int i, j, k; //初始化 for(i=0; i<M; i++) for(j=0; j<M; j++) if(i == j) gg[i][j] = 0; else gg[i][j] = inf; //建图 for(i=0; i<M; i++) for(j=i+1; j<M; j++) if(IsNear(re[i], re[j])) gg[j][i] = gg[i][j] = 1; //flody算法 for(k=0; k<M; k++) for(i=0; i<M; i++) if(i != k) for(j=0; j<M; j++) if(i != j && j != k && gg[i][k] + gg[k][j] < gg[i][j]) gg[i][j] = gg[i][k] + gg[k][j]; int ans=inf, tmp, curval, t; //枚举每一个目的城市 for(i=0; i<M; i++) { for(tmp = j = 0; j<L; j++) { curval = inf; for(k=v[mem[j]].size()-1; k>=0; k--) { t = v[mem[j]][k]; if(gg[t][i] < curval) curval = gg[t][i]; } tmp += curval; } if(ans>tmp) ans = tmp; } printf("%d/n", ans); } int main() { // freopen("in.txt", "r", stdin); while(scanf("%d", &M) != EOF) { getread(); build(); } return 0; }

你可能感兴趣的:(算法,input,Build,IM)