zoukankan      html  css  js  c++  java
  • Walls(floyd POJ1161)

    Walls
    Time Limit: 1000MS   Memory Limit: 10000K
    Total Submissions: 7677   Accepted: 3719

    Description

    In a country, great walls have been built in such a way that every great wall connects exactly two towns. The great walls do not cross each other. Thus, the country is divided into such regions that to move from one region to another, it is necessary to go through a town or cross a great wall. For any two towns A and B, there is at most one great wall with one end in A and the other in B, and further, it is possible to go from A to B by always walking in a town or along a great wall. The input format implies additional restrictions.

    There is a club whose members live in the towns. In each town, there is only one member or there are no members at all. The members want to meet in one of the regions (outside of any town). The members travel riding their bicycles. They do not want to enter any towns, because of the traffic, and they want to cross as few great walls as possible, as it is a lot of trouble. To go to the meeting region, each member needs to cross a number (possibly 0) of great walls. They want to find such an optimal region that the sum of these numbers (crossing-sum, for short) is minimized.

    The towns are labeled with integers from 1 to N, where N is the number of towns. In Figure 1, the labeled nodes represent the towns and the lines connecting the nodes represent the great walls. Suppose that there are three members, who live in towns 3, 6, and 9. Then, an optimal meeting region and respective routes for members are shown in Figure 2. The crossing-sum is 2: the member from town 9 has to cross the great wall between towns 2 and 4, and the member from town 6 has to cross the great wall between towns 4 and 7.

    You are to write a program which, given the towns, the regions, and the club member home towns, computes the optimal region(s) and the minimal crossing-sum.

    Input

    Your program is to read from standard input. The first line contains one integer: the number of regions M, 2 <= M <= 200. The second line contains one integer: the number of towns N, 3 <= N <= 250. The third line contains one integer: the number of club members L, 1 <= L <= 30, L <= N. The fourth line contains L distinct integers in increasing order: the labels of the towns where the members live.

    After that the input contains 2M lines so that there is a pair of lines for each region: the first two of the 2M lines describe the first region, the following two the second and so on. Of the pair, the first line shows the number of towns I on the border of that region. The second line of the pair contains I integers: the labels of these I towns in some order in which they can be passed when making a trip clockwise along the border of the region, with the following exception. The last region is the "outside region" surrounding all towns and other regions, and for it the order of the labels corresponds to a trip in counterclockwise direction. The order of the regions gives an integer labeling to the regions: the first region has label 1, the second has label 2, and so on. Note that the input includes all regions formed by the towns and great walls, including the "outside region".

    Output

    Your program is to write to standard output. The first line contains one integer: the minimal crossing-sum.

    Sample Input

    10
    10
    3
    3 6 9 
    3
    1 2 3 
    3
    1 3 7 
    4
    2 4 7 3 
    3
    4 6 7 
    3
    4 8 6 
    3
    6 8 7 
    3
    4 5 8 
    4
    7 8 10 9 
    3
    5 10 8 
    7
    7 9 10 5 4 2 1

    Sample Output

    2

    Source

    IOI 2000
    以每一个区域为点建立图,然后暴力搜索最小的区域
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    
    using namespace std;
    
    const int INF = 0x3f3f3f3f;
    
    int m,n,L;
    int man[300];//成员
    int Area[250][300];//区域
    int Dis[250][250];//区域之间的距离
    int dis[40];//人到某个区域的距离
    void floyd()//计算区域的最短路
    {
        for(int k=1;k<=m;k++)
        {
            for(int i=1;i<=m;i++)
            {
                for(int j=1;j<=m;j++)
                {
                    if(Dis[i][j]>Dis[i][k]+Dis[k][j])
                    {
                        Dis[i][j]=Dis[i][k]+Dis[k][j];
                    }
                }
            }
        }
    }
    
    int solve()//暴力枚举区域找最小的值
    {
        int Min=INF;
        for(int i=1;i<=m;i++)
        {
            for(int j=1;j<=L;j++)
            {
                dis[j]=INF;
            }
            for(int j=1;j<=m;j++)
            {
                for(int k=1;k<=Area[j][0];k++)
                {
                    if(man[Area[j][k]]>0&&dis[man[Area[j][k]]]>Dis[i][j])
                    {
                        dis[man[Area[j][k]]]=Dis[i][j];
                    }
                }
            }
            int temp=0;
            for(int j=1;j<=L;j++)
            {
                temp+=dis[j];
            }
            Min=min(Min,temp);
        }
        return Min;
    }
    int main()
    {
        int a;
        while(~scanf("%d",&m))
        {
            scanf("%d %d",&n,&L);
            memset(man,0,sizeof(man));
            for(int i=1; i<=L; i++)
            {
                scanf("%d",&a);
                man[a]=i;//在那个点住着的成员编号
            }
           for(int i=1;i<=m;i++)//初始化
           {
               for(int j=i;j<=m;j++)
               {
                   if(i==j)
                   {
                       Dis[i][j]=0;
                   }
                   else
                   {
                       Dis[i][j]=Dis[j][i]=INF;
                   }
               }
           }
            for(int i=1; i<=m; i++)
            {
                scanf("%d",&Area[i][0]);
                for(int j=1; j<=Area[i][0]; j++)
                {
                    scanf("%d",&Area[i][j]);//区域的点集,逆时针方向
                }
                Area[i][Area[i][0]+1]=Area[i][1];//闭合区域
                for(int j=1; j<=Area[i][0]; j++)//判断区域是不是相邻
                {
                    for(int k=1; k<i; k++)
                    {
                        for(int s=1; s<=Area[k][0]; s++)
                        {
                            if(Area[i][j+1]==Area[k][s]&&Area[i][j]==Area[k][s+1])//判断区域是不是邻接
                            {
                                Dis[i][k]=Dis[k][i]=1;
                            }
                        }
                    }
                }
            }
            floyd();
            printf("%d
    ",solve());
        }
        return 0;
    }
    


  • 相关阅读:
    解决DataGridView绑定List后不能排序的问题
    最新的皮肤下载
    我收录的名言
    HttpRequest访问Https带有证书并使用WSDL文档生成代理类方案(2)
    最新的Functions 类
    华兴软通短信接口简单使用WebServices版
    最新的SqlHelper 类
    闲来没事写个记事本玩玩!!!
    "基础连接已经关闭: 未能为 SSL/TLS 安全通道建立信任关系"证书验证失败的解决过程(3)
    FCK配置
  • 原文地址:https://www.cnblogs.com/juechen/p/5255928.html
Copyright © 2011-2022 走看看