• Walls POJ 1161


    参考了大牛的博客 

    http://blog.csdn.net/wangjian8006/article/details/7958838

    题目大意:

    给出n个点,在这些点中有些点是俱乐部点,并且有m个区域是由点围成的
    输入第一行代表n个点
    第二行代表m个区域
    第3行代表俱乐部有L个
    第四行有L个数,分别标记哪些个点事是俱乐部
    接下来2*m行,代表m个区域,每个区域由两行表示,第一行为区域由T个点围成的,
    第二行T个数代表是哪些点围成这个区域,这些点按逆时针围成这个区域,相邻两点代表一条边
    最后一点和第一点也是一条边,这样就是一个闭合的区域

    现在问,在图中找出一个区域,使得所有俱乐部点到这个区域所要穿过的边之和最少,
    输出最少的边数之和

    题目思路:

    建图 假如两个区域有公共边 则 两个区域的距离是 1, 然后 Floyd 求出所有区域的距离。

    剩下的暴力解解决就OK了

    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <cmath>
    #include <cstring>
    using namespace std;
    #define INF 0xfffffff
    #define maxn 260
    
    struct Area
    {
        int num;
        int Point[maxn];
        bool vis[maxn];
    } P[maxn];
    
    int G[maxn][maxn], Member[maxn];
    int n, m, a;//n个点 m个区域 a个座城有俱乐部成员
    
    void Floyd();
    bool Adj(Area A, Area B);
    int Slove();
    int CountPoint(int k);
    
    int main()
    {
        cin >> m >> n >> a;
    
        for(int i=0; i<a; i++)
            cin >> Member[i];
    
        for(int i=0; i<m; i++)
        {
            cin >> P[i].num;
    
            for(int j=0; j<P[i].num; j++)
            {
                cin >> P[i].Point[j];
                P[i].vis[ P[i].Point[j] ] = true;
            }
    
            P[i].Point[P[i].num] = P[i].Point[0];
        }
    
        for(int i=0; i<m; i++)
        {
            for(int j=0; j<i; j++)
            {
                G[i][j] = INF;
                if( Adj(P[i], P[j]) )
                    G[i][j] = 1;
    
                G[j][i] = G[i][j];
            }
            G[i][i] = 0;
        }
    
        Floyd();
    
        int ans = Slove();
    
        cout << ans << endl;
    
        return 0;
    }
    void Floyd()
    {
        for(int k=0; k<m; k++)
        {
            for(int i=0; i<m; i++)
            {
                for(int j=0; j<m; j++)
                {
                    if(G[i][j] > G[i][k] + G[k][j] )
                    {
                        G[i][j] = G[i][k] + G[k][j];
                    }
                }
            }
        }
    }
    
    bool Adj(Area A, Area B)
    {
        for(int i=0; i< A.num; i++)
        {
            for(int j=0; j<B.num; j++)
            {
                if( (A.Point[i] == B.Point[j] && A.Point[i+1] == B.Point[j+1]) ||
                        (A.Point[i] == B.Point[j + 1] && A.Point[i+1] == B.Point[j]) )
                    return true;
            }
        }
        return false;
    }
    
    int Slove()
    {
        int index = 0, b[maxn];
        for(int i=0; i<m; i++)
        {
            b[i] = CountPoint(i);
        }
    
        for(int i=1; i<m; i++)
        {
            if(b[i] < b[index])
                index = i;
        }
        return b[index];
    }
    
    int CountPoint(int k)//计算所有点  到达这个区域k 需要穿越多少条边
    {
        int sum = 0;
    
        for(int i=0; i<a; i++)
        {
            int Min = INF;
            for(int j=0; j<m; j++)
            {
                if( P[j].vis[ Member[i] ] && Min > G[j][k] )
                {
                    Min = G[j][k];
                }
            }
            sum += Min;
        }
        return sum;
    }
  • 相关阅读:
    GoF23种设计模式之行为型模式之中介者模式
    GoF23种设计模式之行为型模式之备忘录模式
    GoF23种设计模式之行为型模式之解释器模式
    GoF23种设计模式之行为型模式之观察者模式
    GoF23种设计模式之行为型模式之状态模式
    GoF23种设计模式之行为型模式之策略模式
    GoF23种设计模式之行为型模式之模板方法
    GoF23种设计模式之行为型模式之访问者模式
    电子地图/卫星地图下载并转存为jpg图片
    webapi swagger学习笔记
  • 原文地址:https://www.cnblogs.com/chenchengxun/p/4174500.html
Copyright © 2020-2023  润新知