目录地址
前言
打错了一个地方之接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);//两遍SPFAsum=-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;
}