比赛 |
咲 -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]);
}
}