您的位置:首页 > 其它

poj 1161 walls

2013-02-02 22:40 309 查看
构图很有趣,我是把区域当成构图的点,然后floyd+枚举每个区域到所有会员的穿过墙的和。求出。

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

View Code

// File Name: 1161.cpp
// Author: Missa
// Created Time: 2013/2/2 星期六 13:46:13

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<string>
#include<vector>
#include<cstdlib>
#include<map>
using namespace std;

const int maxn = 5e2+5;
const int inf = 0x3f3f3f3f;
int n,m,l;
int dis[maxn][maxn];
int ds[maxn][maxn];
bool mem[maxn];
int tmp[maxn];
int main()
{
while(~scanf("%d",&m))
{
scanf("%d%d",&n,&l);
//memset(dis,0x7f,sizeof(dis));
for(int i=0;i<maxn;i++)
for(int j=0;j<maxn;j++)
{
if(i==j) dis[i][j]=0;
else dis[i][j]=inf;
}
memset(mem,0,sizeof(mem));
memset(ds,0,sizeof(ds));
int x;
for(int i=0;i<l;i++)
{
scanf("%d",&x);
mem[x]=1;
}
for(int i=1;i<=m;i++)
{
scanf("%d",&x);
for(int j=0;j<x;j++)
{
scanf("%d",&tmp[j]);
if(mem[tmp[j]])
dis[m+tmp[j]][i]=dis[i][m+tmp[j]]=0;
}
tmp[x]=tmp[0];
for(int k=0;k<x;k++)
{
int tt=ds[tmp[k]][tmp[k+1]];
if(tt==0)
ds[tmp[k]][tmp[k+1]]=ds[tmp[k+1]][tmp[k]]=i;
else
dis[i][tt]=dis[tt][i]=1;
}
}
for(int k=1;k<=m;k++)
for(int i=1;i<=m;i++)
for(int j=1;j<=m;j++)
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
if(mem[j] && dis[i][m+j]==0)
{
for(int k=1;k<=m;k++)
{
if(dis[m+j][k]>dis[i][k])
dis[m+j][k]=dis[k][m+j]=dis[i][k];
}
}
}
}
int ans=inf;
int tt=0;
for(int i=1;i<=m;i++)
{
tt=0;
for(int j=1;j<=n;j++)
{
if(mem[j])
{
tt+=dis[i][m+j];
//    cout<<"dis:"<<i<<" "<<j<<" ="<<dis[i][m+j]<<endl;
}
}
if(tt<ans)
ans=tt;
//cout<<"区域:"<<i<<" tmp="<<tmp<<endl;
}
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: