【题目大意】
给定N个珠子,从1到N编号,然后是M个配对关系(x,y),表示珠子x和y可以相邻,要求用最少的珠子组成串,且所用珠子个数是大于或等于3的奇数,求这个最小的珠子个数的值。
【详细分析】
刚开始看到题,是自己刚刚挂的一个DIY:2008“Sunline Cup”邀请赛里的第一题,大概的想了下,觉得可以转换成最小环来做,刚好自己会最小环(可以参考我的最小环相关博文,很详细)。数据量是1000,觉得Floyd算法应该可以吧,就写了,结果是超时。赛后自己百度,看了很多讲解,下面给出整理之后的详细题解。
对于该类题目 分析了下复杂度 可以对各个点进行一一枚举 对于每次的枚举 记录访问到该点时的深度 当下一次访问时只要将当前深度加上访问到该点的深度就能计算出总共所用去的点数 使用2个队列 以形成逐层遍历(保证了路径的不重复) 感觉很不错 每次枚举计算出的最小值可以作为下一次的阀值 从而达到了缩小规模的目的
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
struct point
{
int x,y;
friend bool operator<(point a,point b)
{
if(a.x!=b.x)
return a.x>b.x;
return a.y>b.y;
}
};
int main()
{
int m,n,i,j,k,h;
int ans,sum;
point cur,in;
scanf("%d",&n);
while(n--)
{
priority_queue<point>q;
scanf("%d",&m);
for(i=0;i<m;i++)
{
scanf("%d%d",&cur.x,&cur.y);
q.push(cur);
}
ans=0;
sum=0;
while(!q.empty())
{
sum++;
cur=q.top();
q.pop();
if(ans<cur.x)
ans=cur.x;
if(sum%2==0)
continue;
in.x=cur.x+cur.y;
in.y=cur.y;
q.push(in);
}
printf("%d\n",ans);
}
return 0;
}