poj 1161 walls

构图很有趣,我是把区域当成构图的点,然后floyd+枚举每个区域到所有会员的穿过墙的和。求出。

开始wa是想错了一个地方。就是没看清题目给的区域点是按逆时针给出。。。然后竟然把一个区域的所有点都当成是可以连接的边了。。。囧。。其实很简单。。可是搞了很久。。

View Code
  1 // File Name: 1161.cpp

  2 // Author: Missa

  3 // Created Time: 2013/2/2 星期六 13:46:13

  4 

  5 #include<iostream>

  6 #include<cstdio>

  7 #include<cstring>

  8 #include<algorithm>

  9 #include<cmath>

 10 #include<queue>

 11 #include<stack>

 12 #include<string>

 13 #include<vector>

 14 #include<cstdlib>

 15 #include<map>

 16 using namespace std;

 17 

 18 const int maxn = 5e2+5;

 19 const int inf = 0x3f3f3f3f;

 20 int n,m,l;

 21 int dis[maxn][maxn];

 22 int ds[maxn][maxn];

 23 bool mem[maxn];

 24 int tmp[maxn];

 25 int main()

 26 {

 27     while(~scanf("%d",&m))

 28     {

 29         scanf("%d%d",&n,&l);

 30         //memset(dis,0x7f,sizeof(dis));

 31         for(int i=0;i<maxn;i++)

 32             for(int j=0;j<maxn;j++)

 33             {

 34                 if(i==j) dis[i][j]=0;

 35                 else dis[i][j]=inf;

 36             }

 37         memset(mem,0,sizeof(mem));

 38         memset(ds,0,sizeof(ds));

 39         int x;

 40         for(int i=0;i<l;i++)

 41         {

 42             scanf("%d",&x);

 43             mem[x]=1;

 44         }

 45         for(int i=1;i<=m;i++)

 46         {

 47             scanf("%d",&x);

 48             for(int j=0;j<x;j++)

 49             {

 50                 scanf("%d",&tmp[j]);

 51                 if(mem[tmp[j]])

 52                     dis[m+tmp[j]][i]=dis[i][m+tmp[j]]=0;

 53             }

 54             tmp[x]=tmp[0];

 55             for(int k=0;k<x;k++)

 56             {

 57                 int tt=ds[tmp[k]][tmp[k+1]];

 58                 if(tt==0)

 59                     ds[tmp[k]][tmp[k+1]]=ds[tmp[k+1]][tmp[k]]=i;

 60                 else

 61                     dis[i][tt]=dis[tt][i]=1;

 62             }

 63         }

 64         for(int k=1;k<=m;k++)

 65             for(int i=1;i<=m;i++)

 66                 for(int j=1;j<=m;j++)

 67                     dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);

 68         for(int i=1;i<=m;i++)

 69         {

 70             for(int j=1;j<=n;j++)

 71             {

 72                 if(mem[j] && dis[i][m+j]==0)

 73                 {

 74                     for(int k=1;k<=m;k++)

 75                     {

 76                         if(dis[m+j][k]>dis[i][k])

 77                             dis[m+j][k]=dis[k][m+j]=dis[i][k];

 78                     }

 79                 }

 80             }

 81         }

 82         int ans=inf;

 83         int tt=0;

 84         for(int i=1;i<=m;i++)

 85         {

 86             tt=0;

 87             for(int j=1;j<=n;j++)

 88             {

 89                 if(mem[j])

 90                 {

 91                     tt+=dis[i][m+j];

 92                 //    cout<<"dis:"<<i<<" "<<j<<" ="<<dis[i][m+j]<<endl;

 93                 }

 94             }

 95             if(tt<ans)

 96                 ans=tt;

 97             //cout<<"区域:"<<i<<" tmp="<<tmp<<endl;

 98         }

 99         printf("%d\n",ans);

100     }

101     return 0;

102 }

 

你可能感兴趣的:(poj)