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 }

 

posted @ 2013-02-02 22:40  Missa  阅读(190)  评论(0编辑  收藏  举报