Floyd 求最短路(poj 1161)

Posted yoyo_sincerely

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Floyd 求最短路(poj 1161)相关的知识,希望对你有一定的参考价值。

题目:Walls

题意:给定一个图,求其中几个点相连最少要穿越的边数。

思路:这题的图要重新建,不能用原图,新图是这样的:将一个圈化为点,之间的关系是两个圈是否有公共边,然后就是求最短路问题了;

 

#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <time.h>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>
#include <set>


#define c_false ios_base::sync_with_stdio(false); cin.tie(0)
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3f
#define zero_(x,y) memset(x , y , sizeof(x))
#define zero(x) memset(x , 0 , sizeof(x))
#define MAX(x) memset(x , 0x3f ,sizeof(x))
#define swa(x,y) {LL s;s=x;x=y;y=s;}
using namespace std ;
#define N 500

const double PI = acos(-1.0);
typedef long long LL ;
int mapp[N][N], region[N][N], p_num[N], n, m, r;
struct Person{
    int adr;
    int t;      ///所在环数;
    int reg[N]; ///
}person[N];

int find_dis(int i, int j){  ///寻找i,j 两区域间的边,若没有,返回-1
    int ii, jj;
    for(ii = 1; ii <= p_num[i]; ii++){
        for(jj = 1; jj <= p_num[j]; jj++){
            if(region[i][ii] == region[j][jj]){
                if(region[i][ii+1] == region[j][jj+1] || region[i][ii+1] == region[j][jj-1] ||
                   region[i][ii-1] == region[j][jj+1] || region[i][ii-1] == region[j][jj-1])
                    return 1;
            }
        }
    }
    return -1;
}

void Floyd(){     ///寻找最短路
    int i, j, k;
    for(k = 1; k<= m; k++)
        for(i = 1; i<= m; i++)
            for(j = 1; j<= m; j++)
                mapp[i][j] = mapp[j][i] = min(mapp[i][j], mapp[i][k]+mapp[k][j]);
}

int search_(int i){  //查找i区域到俱乐部每个成员间的距离和;
    int j, k, s = 0;
    for(j = 1; j<= r;j++){
        int d = INF;
        for(k = 1; k <=person[j].t; k++)
            d = min(d, mapp[person[j].reg[k]][i]);
        s+=d;
    }
    return s;
}
int main(){
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int i,j,k;
    while(~scanf("%d",&m)){
        scanf("%d%d",&n,&r);
        for(i = 1; i<= r;i++){
            scanf("%d",&person[i].adr);
            person[i].t = 0;
        }
        for(i = 1; i <= m; i++){
            scanf("%d", &p_num[i]);
            for(j = 1; j <= p_num[i]; j++){
                scanf("%d", &region[i][j]);
                for(k = 1; k <= r; k++){
                    if(person[k].adr == region[i][j])
                        person[k].reg[ ++person[k].t] = i;
                }
            }
            region[i][0] = region[i][ p_num[i] ];
            region[i][p_num[i]+1] = region[i][1];
        }
        for(i = 1; i <= m; i++){
            for(j = 1; j<=m; j++){
                if(i == j){
                    mapp[i][j] = mapp[j][i] = 0;continue;
                }
                int ans = find_dis(i, j);
                if(ans == 1) mapp[i][j] = mapp[j][i] =1;
                else mapp[i][j] = mapp[j][i] =INF;
            }
        }
        Floyd();
        int min_dis = search_(1);
        for(i = 2; i <=m ;i++){
            int  d =search_(i);
            min_dis = min(d, min_dis);
        }
        printf("%d\n",min_dis);
    }
    return 0;
}

 

以上是关于Floyd 求最短路(poj 1161)的主要内容,如果未能解决你的问题,请参考以下文章

a*算法求最短路径和floyd还有dijsktra算法求最短路径的区别?

POJ 1161 Walls ( Floyd && 建图 )

Floyd求最短路

Floyd求最短路

Floyd求最短路

POJ 1161 Walls(最短路+枚举)