前言
打错了一个地方之接60,还有输出“Peace”能拿60。还有题目坑爹害得我用了哈希,可以无视 QAQ
正题
有一个n*n的图,有m条边,不知道几个城市,给出两个位置,求两个位置移动到相遇(不能再路上)的最短路径。
输入输出(需要自取)
Input
输入数据第一行:N和M(用空格隔开) 表示这是一个N*N的图并且有M条边,第二行到第M+1行 为这个图的详细信息。
每行共有被空格隔开的三个数:a b c。表示编号为a的城市到编号为b的城市
有一个双向边,并且要过这条双向边所需要花费的时间为c。
最后一行有两个数:S和T,S表示腾讯所处的城市(也就是深圳),T表示360所处的
城市(也就是北京)
Output
输出只有一行,D,表示二者“相遇”的最短时间。当然,如果无法相遇则输出“Peace!”
Sample Input
3 3
1 2 1
2 3 1
1 3 1
1 3
Sample Output
1
解题思路
两遍SPFA,然后枚举相遇点。无视哈希
代码
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int p=29989,air=-117901064;
struct woc{
int x,y,w,next;
};
int n,m,sum,f[p+1],ls[p+1],f2[p+1],hash[p+1],state[p+1],head,tail,num;
bool v[p+1];
woc line[10001];
int hashmath(int x)
{
return abs(x)%p;
}
int locate(int x)
{
int wz=hashmath(x);
int i=0;
while (i<p && hash[(wz+i)%p]!=x && hash[(wz+i)%p]!=air)
i++;
return (wz+i)%p;
}
void Spfa(int x)//SPFA不解释
{
memset(f,127/3,sizeof(f));
state[1]=locate(x);v[state[1]]=true;f[state[1]]=0;
int w=0;
head=0;tail=1;
do
{
head=head%p+1;
w=ls[state[head]];
while (w!=0)
{
if (f[line[w].x]+line[w].w<f[line[w].y])
{
f[line[w].y]=f[line[w].x]+line[w].w;
if (!v[line[w].y])
{
v[line[w].y]=true;
tail=tail%p+1;
state[tail]=line[w].y;
}
}
w=line[w].next;
}
v[state[head]]=false;
}
while (head!=tail);
}
void Spfa2(int x)
{
memset(f2,127/3,sizeof(f2));
state[1]=locate(x);v[state[1]]=true;f2[state[1]]=0;
int w=0;
head=0;tail=1;
do
{
head=head%p+1;
w=ls[state[head]];
while (w!=0)
{
if (f2[line[w].x]+line[w].w<f2[line[w].y])
{
f2[line[w].y]=f2[line[w].x]+line[w].w;
if (!v[line[w].y])
{
v[line[w].y]=true;
tail=tail%p+1;
state[tail]=line[w].y;
}
}
w=line[w].next;
}
v[state[head]]=false;
}
while (head!=tail);
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=0;i<p;i++) hash[i]=air;
int xx,yy,ww,wz1,wz2;
for (int i=1;i<=m;i++)
{
scanf("%d%d%d",&xx,&yy,&ww);
wz1=locate(xx);wz2=locate(yy);
if (hash[wz1]==air) hash[wz1]=xx;
if (hash[wz2]==air) hash[wz2]=yy;
line[++num].x=wz1;
line[num].y=wz2;
line[num].w=ww;
line[num].next=ls[wz1];
ls[wz1]=num;
line[++num].x=wz2;
line[num].y=wz1;
line[num].w=ww;
line[num].next=ls[wz2];
ls[wz2]=num;//无向图建邻接表
}
scanf("%d%d",&xx,&yy);
Spfa(xx);
Spfa2(yy);//两遍SPFA
sum=-air;
for (int i=0;i<p;i++)//枚举相遇点
{
if (hash[i]!=air)
{
sum=min(sum,max(f[i],f2[i]));//更新最大值
}
}
if (sum==-air) printf("Peace!");//判断无法相遇
else printf("%d",sum);
return 0;
}