您的位置:首页 > 其它

A - Tea-drinking-Gym 100703A-优先队列/最小生成树

2015-08-06 04:10 309 查看
http://codeforces.com/gym/100703/problem/A

题意是n行字符串,长度m

先按题目求出每行之间的“距离”

然后要求 把所有字符串连起来, 输出生成数 中 两个字符串距离的最大值

法1

此题可以 先对for两遍 o(n^2) n=1000求出所有边

然后按边权升序排序, 然后 每天添加一条边就用并查集把两个点合并,

如果取出的边 的两点根节点想同,就丢掉,否则选取 最后得到的也是最优的

//////////////////////////////////////////////////////////////////////////////

法2

当时我是用优先队列做的 ,先得到一条距离最小的边

vis标记掉两个点

然后把 所有与这两个顶点 连的所有边 都丢到优先队列里

然后取出最顶端的,即最小的边,如果不满足 ( 一端点被选过,另一端点没被选过) 就丢掉,如果满足就选取该边

并把该没选过的点用vis标记为选过,

然后把 所有与这一个顶点 连的所有边 都丢到优先队列里

不断重复 也是最优的 不过麻烦了点

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<string>
#include<string.h>
#include<stack>
#include<queue>
#define MAX 1000005
#define inf 0x3f3f3f3f
#define ll long long
using namespace std;
struct node
{
	int dist;
	int x;
	bool operator < (const node&  b) const
	{
		return dist>b.dist;
	}
};
 int ans[1005][1005];
char tm[1005][35];
int n,m;
int ok=0;
int min_point_x=0;
int min_point_y=0;
int mark=900;
int cal(int x1,int x2)
{
	int i;
	int maxx=0;
	for (i=1;i<=m;i++)
	{
		if (abs(tm[x1][i]-tm[x2][i])>maxx)
			maxx=abs(tm[x1][i]-tm[x2][i]);
	}
		 
			ans[x1][x2]=maxx;

		if (maxx<mark)
		{
			mark=maxx;
			 min_point_x=x1;
			 min_point_y=x2;
		}
	//  cout<<x1<<"---"<<x2<<"---dist:"<<maxx<<endl; 
		return 0;
}
int cmp(node a,node b)
{
	return a.dist<b.dist;
}
int vis[1005];

priority_queue <node> qq;
int main()
{
	int i,j;
    scanf("%d%d",&n,&m);
	getchar();

	for (i=1;i<=n;i++)
	{
		scanf("%s",tm[i]+1); 
	}
 	for (i=1;i<=n;i++)
	{
		for (j=1;j<=n;j++)
		{
			if (j==i) continue;
			cal(i,j);
		} 
	} 
 

	int maxxxx=0;   
	node tmp;
	tmp.x= min_point_x;

	vis[tmp.x] =1;
node ttt;
	for (i=1;i<=n;i++)
	{
		if (ans[tmp.x][i]==0||vis[i]==1) continue; 
		ttt.x=i;
		ttt.dist=ans[tmp.x][i];
		qq.push(ttt);
	}
		    	tmp.x= min_point_y;
					vis[tmp.x] =1;
		for (i=1;i<=n;i++)
	{
		if (ans[tmp.x][i]==0||vis[i]==1) continue; 
		ttt.x=i;
		ttt.dist=ans[tmp.x][i];
		qq.push(ttt);
	}
  node tm;
while(!qq.empty())
{
	 tm=qq.top();
	 qq.pop();
		if (vis[tm.x]==1) continue;
		vis[tm.x]=1;
		
	 if (tm.dist>mark)
		 mark=tm.dist;
		for (i=1;i<=n;i++)
	{
		if (ans[tm.x][i]==0||vis[i]==1) continue; 
		ttt.x=i;
		ttt.dist=ans[tm.x][i];
		qq.push(ttt);
	}

}

	
	printf("%d\n",mark);
				
				return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: