比赛 咲 -Saki- 互测赛 评测结果 AA
题目名称 一起进军全国吧 最终得分 100
用户昵称 Citron酱 运行时间 0.003 s
代码语言 C++ 内存使用 1.94 MiB
提交时间 2012-07-19 11:49:19
显示代码纯文本
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <iostream>

#define I_F "zengokuhe.in"
#define O_F "zengokuhe.out"

using std::string;

const long MAXn=100000;
const int MAXl=1000;
const int P=32767;

struct edge
{
	long x;
	double l;
	edge *next;
};

struct treap
{
	long x,z;
	string s;
	treap *father, *left, *right;
};

struct que
{
	long x;
	que *next;
};

long n=1, m;
string q[MAXn];
edge *map[MAXn]={NULL};
double d[MAXn];
bool f[MAXn]={false};
treap *root=NULL;

inline void Left_turn(treap*);
inline void Right_turn(treap*);
void Clear(char*);
inline double Abs(const double&);
void Insert(const string&, const long&);
long Find(const string&);
void Input();
void Spfa();
void Output();

int main()
{
	Input();
	Spfa();
	Output();
	return 0;
}

inline void Left_turn(treap *p)
{
	treap *f=p->father, *b=p->right;
	if (f->father==NULL)
		root=p;
	else
		if (f==f->father->left)
			f->father->left=p;
		else
			f->father->right=p;
	p->father=f->father;
	f->father=p;
	p->right=f;
	f->left=b;
	if (b!=NULL)
		b->father=f;
}

inline void Right_turn(treap *f)
{
	treap *p=f->father, *b=f->left;
	if (p->father==NULL)
		root=f;
	else
		if (p==p->father->left)
			p->father->left=f;
		else
			p->father->right=f;
	f->father=p->father;
	p->father=f;
	f->left=p;
	p->right=b;
	if (b!=NULL)
		b->father=p;
}

void Clear(char *s)
{
	for (int i=0; i<MAXl; ++i)
		s[i]=0;
}

inline double Abs(const double &x)
{
	return (x>0)?x:-x;
}

void Insert(const string &s, const long &x)
{
	if (root==NULL)
	{
		root=new treap;
		root->s=s;
		root->x=x;
		root->z=rand()%P;
		root->father=root->left=root->right=NULL;
	}
	else
	{
		treap *i=root;
		bool flag=true;
		while (flag)
			if (s<i->s)
				if (i->left==NULL)
				{
					i->left=new treap;
					i->left->father=i;
					i=i->left;
					i->s=s;
					i->x=x;
					i->z=rand()%P;
					i->left=i->right=NULL;
					flag=false;
				}
				else
					i=i->left;
			else
				if (i->right==NULL)
				{
					i->right=new treap;
					i->right->father=i;
					i=i->right;
					i->s=s;
					i->x=x;
					i->z=rand()%P;
					i->left=i->right=NULL;
					flag=false;
				}
				else
					i=i->right;
		while (i->father!=NULL && i->z>i->father->z)
			if (i==i->father->left)
				Left_turn(i);
			else
				Right_turn(i);
	}
}

long Find(const string &s)
{
	if (root==NULL)
		return -1;
	for (treap *i=root; i!=NULL; )
		if (s<i->s)
			i=i->left;
		else if (s>i->s)
			i=i->right;
		else
			return i->x;
	return -1;
}

void Input()
{
	using std::cin;
	freopen(I_F,"r",stdin);
	char t[MAXl]={0}, temp[MAXl];
	string tem;
	double tnum,nlast;
	long lt, llast;
	edge *te;
	scanf("%ld %s\n",&m,t);
	tem.clear();
	tem=t;
	Insert(tem,0);
	for (int i=0; i<m; ++i)
	{
		Clear(t);
		scanf("%s\n",t);
		q[i]=t;
	}
	Clear(t);
	fgets(t,MAXl,stdin);
	while (strlen(t)>0)
	{
		Clear(t);
		fgets(t,MAXl,stdin);
		if (t[0]!='S' && strlen(t)>0)
		{
			Clear(temp);
			if (t[0]>='0' && t[0]<='9')
				sscanf(t,"%lf %s",&tnum,temp);
			else
				sscanf(t,"%s %lf",temp,&tnum);
			tem.clear();
			tem=temp;
			lt=Find(tem);
			if (lt==-1)
			{
				Insert(tem,n);
				lt=n++;
			}
			Clear(t);
			fgets(t,MAXl,stdin);
			while (t[0]!='S' && strlen(t)>0)
			{
				llast=lt;
				nlast=tnum;
				Clear(temp);
				if (t[0]>='0' && t[0]<='9')
					sscanf(t,"%lf %s",&tnum,temp);
				else
					sscanf(t,"%s %lf",temp,&tnum);
				tem.clear();
				tem=temp;
				lt=Find(tem);
				if (lt==-1)
				{
					Insert(tem,n);
					lt=n++;
				}
				te=map[llast];
				map[llast]=new edge;
				map[llast]->x=lt;
				map[llast]->l=Abs(tnum-nlast);
				map[llast]->next=te;
				te=map[lt];
				map[lt]=new edge;
				map[lt]->x=llast;
				map[lt]->l=map[llast]->l;
				map[lt]->next=te;
				Clear(t);
				fgets(t,MAXl,stdin);
			}
		}
	}
}

void Spfa()
{
	for (long i=0; i<n; ++i)
		d[i]=-1;
	d[0]=0;
	f[0]=true;
	que *head=new que;
	que *tail=head, *temp;
	head->x=0;
	head->next=NULL;
	while (head!=NULL)
	{
		for (edge *i=map[head->x]; i!=NULL; i=i->next)
			if (d[i->x]==-1 || d[head->x]+i->l<d[i->x])
			{
				d[i->x]=d[head->x]+i->l;
				if (!f[i->x])
				{
					f[i->x]=true;
					tail->next=new que;
					tail=tail->next;
					tail->x=i->x;
					tail->next=NULL;
				}
			}
		temp=head;
		head=head->next;
		f[temp->x]=false;
		delete temp;
	}
}

void Output()
{
	long t;
	freopen(O_F,"w",stdout);
	for (long i=0; i<m; ++i)
	{
		t=Find(q[i]);
		if (t==-1)
			printf("-1.0\n");
		else
			printf("%lf\n",d[t]);
	}
}