题目大意:第一行给出n代表有n张地图碎片,接下来n行给出碎片上的信息,第一个单词代表这个碎片上的节点,后边所有的节点都与第一个节点相连接.
最后一行给出查询,问从A到B是否存在一条路径可以通过给定的拼图的一部分拼凑而成,可行的话输出路径,否则输出no route find
可能是比赛当时受了先前题目的影响,看到这题之后第一时间想到的就是最短路,题目保证了最多只有一条路.因此,只需要把每个节点名字一一对应成id,id对应节点,然后跑一次最短路,然后找出那条路径即可.
其中有一个数据一直没过:因为映射的时候id从0开始标记,而默认的map影射也是从0开始的,如果id从1开始可以自动避过这个坑.
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
int n;
int cnt;
map<string,int>m;
map<int,string> mm;
vector<string>v;
string s;
int vis[5000],dis[5000],pre[5000];
int G[5000][5000];
void init()
{
m.clear();
mm.clear();
for(int i=0;i<5000;i++){
for(int j=0;j<5000;j++){
if(i==j)G[i][j]=0;
else G[i][j]=inf;
}
}
memset(dis,inf,sizeof(dis));
memset(vis,0,sizeof(vis));
memset(pre,-1,sizeof(pre));
cnt=0;
getline(cin,s);
for(int i=0; i<n; i++)
{
v.clear();
getline(cin,s);
string temp = "";
for(int i=0; i<s.size(); i++)
{
if(s[i]==' ')
{
v.push_back(temp);
temp="";
continue;
}
else temp+=s[i];
}
v.push_back(temp);
for(int i=0;i<v.size();i++){
if(m.count(v[i])==0){
m[v[i]]=cnt;
mm[cnt]=v[i];
cnt++;
}
}
//cout<<m[v[0]]<<endl;
for(int i=1;i<v.size();i++)
G[m[v[0]]][m[v[i]]]=G[m[v[i]]][m[v[0]]]=1;
}
// for(int i=0;i<cnt;i++){
// for(int j=0;j<cnt;j++){
// cout<<G[i][j]<<" ";
// }
// cout<<endl;
// }
}
void dij(int st){
dis[st]=0;
vis[st]=1;
for(int i=0; i<cnt; i++)
{
int minnum=inf,next=st;
for(int j=0; j<cnt; j++)
{
if(vis[j]==0&&minnum>dis[j])
{
minnum=dis[j];
next=j;
}
}
vis[next]=1;
for(int j=0; j<cnt; j++)
{
if(vis[j]==0)
{
if(dis[j]>dis[next]+G[next][j])
{
dis[j]=dis[next]+G[next][j];
pre[j]=next;
}
}
}
}
}
void path(int ed)
{
if(pre[ed]!=-1)
{
path(pre[ed]);
cout<<mm[pre[ed]]<<" ";
}
}
int main()
{
//freopen("1.txt", "r", stdin);
std::ios::sync_with_stdio(false);
cin>>n;
init();
string sst,sed;
cin>>sst>>sed;
if(m.count(sst)==0||m.count(sed)==0){
cout<<"no route found"<<endl;
return 0;
}
dij(m[sst]);
//cout<<dis[m[sed]]<<endl;
if(dis[m[sed]]==inf)
cout<<"no route found"<<endl;
else {
path(m[sed]);
cout<<mm[m[sed]];
}
return 0;
}