poj 1161

自己总算真正独立的做了一道题,我的思路是这样的:将每一个区域抽象成一个节点,结果就是每个club成员到某一点的最小距离之和。关键就是构图了,每一块相邻的区域,就是直连的两节点,也就是说原图中的每一条边有且仅关联两个区域。在构造图的过程中需要保留club的每个成员可以出发的区域。重新构造图之后对每个顶点进行一次广搜找出最小值就行了。代码如下:

#include<iostream>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
#define MAX_INT 1234567890
struct node
{
	int i;
	int floor;
};
int edge[255][255],member[255],visit[255],floor[255];
vector <int> map[255];
vector <int> start[255];
int bfs(int s)
{
	int j,k;
	queue <node> Q;
	node e={s,0};
	Q.push(e);floor[e.i]=0;
	visit[e.i]=1;
	while(!Q.empty())
	{
		e=Q.front();
		Q.pop();
		k=e.i;
		for(j=0;j<map[k].size();j++)
		{
			node e1={map[k][j],e.floor+1};
			if(!visit[e1.i])
			{
				Q.push(e1);
				visit[e1.i]=1;
				floor[e1.i]=e1.floor;
			}
		}
	}
	return 0;
}
int main()
{
     int i,j,k,s,nCity,nRegin,num,sum,min,min1,cur,pre,first;
	 while(cin>>nRegin>>nCity)
	 {
		 cin>>num;
		 for(i=0;i<num;i++)
			 cin>>member[i];
		 memset(edge,0,sizeof(edge));
		 memset(visit,0,sizeof(visit));
		 //构图
		 for(i=1;i<=nRegin;i++)
		 {
			 cin>>s>>pre;
			 first=pre;
			 start[pre].push_back(i);//保留每个顶点可以出发的区域
			 for(j=1;j<s;j++)
			 {
				 cin>>cur;
                 start[cur].push_back(i);
				 //确定相邻节点
				 if(!edge[pre][cur])
				 {
					 edge[pre][cur]=i;
					 edge[cur][pre]=i;
				 }
				 else
				 {
					 map[edge[pre][cur]].push_back(i);
					 map[i].push_back(edge[pre][cur]);
				 }
				 pre=cur;
			 }
			 if(!edge[cur][first])
			 {
				 edge[cur][first]=i;
				 edge[first][cur]=i;
			 }
			 else
			 {
				 map[edge[cur][first]].push_back(i);
				 map[i].push_back(edge[cur][first]);
			 }
		 }
		 //对每个顶点开始进行广搜
		 min1=MAX_INT;
         for(i=1;i<=nRegin;i++)
		 {
			 memset(floor,0,sizeof(floor));
			 memset(visit,0,sizeof(visit));
			 bfs(i);
			 sum=0;
			 for(j=0;j<num;j++)
			 {
				 s=member[j];min=MAX_INT;
				 for(k=0;k<start[s].size();k++)
				 {
					 //确定每个成员从可与出发的区域到目的区域的最短距离
					 if(min>floor[start[s][k]]) min=floor[start[s][k]];
				 }
				 sum+=min;
			 }
			 if(min1>sum) min1=sum;
		 }
		 cout<<min1<<endl;
		 for(i=0;i<=nRegin;i++)
			 map[i].clear();
		 for(i=1;i<=nCity;i++)
			 start[i].clear();
	 }
	 return 0;
}

posted @ 2011-07-18 17:43  书山有路,学海无涯  阅读(453)  评论(0编辑  收藏  举报