[poj1161]平面图缩点

来源:互联网 发布:情感分类 知乎 编辑:程序博客网 时间:2024/05/01 12:52

题目大意

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.

算法思路

  1. 这是一个平面图,我们要计算的是从多个点到一个面需要穿过多少条边。
  2. 首先,我们将每个面缩成一个点,由于老的点可能在多个面的边界。所以我们先要计算这一点。
  3. 其次,相邻的面的距离为1,其条件是有一条公共边。一开始我先入为主认为就是有两个公共顶点,结果WA了很长时间,伤心。这样的几何边界可不一定是凸多边形啊。
  4. 然后就十分简单了,使用floyd-warshell算法计算任意两对顶点之间的距离,然后枚举每个面的最小叉边数,就可以得到最后的解。

代码

#include<iostream>#include<cstdio>#include<set>#include<vector>#include<cstring>#include<algorithm>using namespace std;#define MAXM 205#define MAXL 35#define INF 0x3f3f3f3fint grid[MAXM][MAXM];vector<int>People[MAXL];int LiveIn[MAXL];int n,m,l;int regionNum[MAXM];vector<int>CityList[MAXM];bool Judge(int st,int en){    int i,j;    for(i=0;i<regionNum[st];i++){        for(j=0;j<regionNum[en];j++){            if(CityList[st][i] == CityList[en][j]){                if(CityList[st][(i+1)%regionNum[st]]==CityList[en][(j-1+regionNum[en])%regionNum[en]])return true;                else if(CityList[st][(i+1)%regionNum[st]]==CityList[en][(j+1)%regionNum[en]])return true;                else if(CityList[st][(i-1+regionNum[st])%regionNum[st]]==CityList[en][(j-1+regionNum[en])%regionNum[en]])return true;                else if(CityList[st][(i-1+regionNum[st])%regionNum[st]]==CityList[en][(j+1)%regionNum[en]])return true;            }        }    }    return false;}void get_map(){    int i,j,k;    for(i=0;i<m;i++){        for(j=i;j<m;j++){            if(i==j)grid[i][j]=0;            else{                if(Judge(i,j)){                    //printf("%d%d\n",i,j);                    grid[i][j] = grid[j][i] = 1;                }                else grid[i][j] = grid[j][i] = INF;            }        }    }    for(i=0;i<l;i++){        for(j=0;j<m;j++){            for(k=0;k<regionNum[j];k++){                if(CityList[j][k] == LiveIn[i]){                    People[i].push_back(j);                    break;                }            }        }    }}void Floyd(){    int i,j,k;    for(i=0;i<m;i++){        for(j=0;j<m;j++){            for(k=0;k<m;k++){                if(grid[j][k]>grid[j][i]+grid[i][k])                    grid[j][k] = grid[j][i]+grid[i][k];            }        }    }}void Solve(){    int ans = INF;    int i,j,k;    Floyd();    /*for(i=0;i<l;i++){        for(j=0;j<People[i].size();j++)            printf("%d ",People[i][j]);        printf("\n");    }*/    for(i=0;i<m;i++){        int tmp=0;        for(j=0;j<l;j++){            int tmp2=INF;            for(k=0;k<People[j].size();k++){                if(grid[People[j][k]][i]<tmp2)                    tmp2 = grid[People[j][k]][i];            }            tmp+=tmp2;        }        //printf("%d\n",tmp);        if(tmp<ans)ans=tmp;    }    printf("%d\n",ans);    return;}int main(){    freopen("WALLS4.in","r",stdin);    int i,j,tmp;    scanf("%d%d",&m,&n);    scanf("%d",&l);    for(i=0;i<l;i++)        scanf("%d",&LiveIn[i]);    for(i=0;i<m;i++){        scanf("%d",&regionNum[i]);        for(j=0;j<regionNum[i];j++){            scanf("%d",&tmp);            CityList[i].push_back(tmp);        }    }    get_map();    Solve();    return 0;}
0 0
原创粉丝点击