目的:帮别人找到去目的地的最快的路径
输入:
N <=100 线路条数
线路格式:
M S[1] S[2] ...S[M]
M <=100 线路上站点数
S[I] 站点的标号,4位数字,0000~9999
注意:
可以有环路,但是没有自循环
有些站可能是中转站,但是每个站最多连接不超过5条线路。
K <=10 查询数字
开始站点 目的站点
输出:
输出最少的经过的站点
然后输出最优的路径,按照规定格式。
每一个查询的路径,要输出经过的线路,线路上的出发点的终点。
如果最优路径不唯一,输出最少中转的路径。
算法:
把边记录下来,然后是图,然后用层序遍历,找到最短路径,然后比较几个最短路径中,哪条中转的次数最少,然后记录下来。
由于每个边属于哪条线路是固定的,所以为每一条边存一个线路。用节点链表存边。
#include<stdio.h>
#include<vector>
#include<algorithm>
using namespace std;
const int inf = 1000000000;
const int maxn = 10010;
struct node{
int indice;
int line;
};
int N,M,K,start,end1;
int minline,mincnt;
vector<node> g[maxn];
vector<node> path,temp;
int vis[maxn] = {0};
void DFS(int now,int line,int cnt,int prel)
{
if(cnt>mincnt) return;
if(now == end1)
{
if(cnt<mincnt)
{
mincnt = cnt;
minline = line;
path = temp;
}else if(cnt==mincnt&&line<minline)
{
minline = line;
path = temp;
}
return;
}
for(int i=0;i<g[now].size();i++)
{
node v = g[now][i];
if(vis[v.indice]==0)
{
vis[v.indice] = 1;
temp.push_back(v);
if(prel!=v.line)
{
DFS(v.indice,line+1,cnt+1,v.line);
}else
{
DFS(v.indice,line,cnt+1,prel);
}
temp.pop_back();
vis[v.indice] = 0;
}
}
}
int main()
{
scanf("%d",&N);
for(int i=1;i<=N;i++)
{
scanf("%d",&M);
int u,v;
scanf("%d",&u);
for(int j=1;j<M;j++)
{
scanf("%d",&v);
g[u].push_back(node{v,i});
g[v].push_back(node{u,i});
u = v;
}
}
scanf("%d",&K);
for(int i=0;i<K;i++)
{
fill(vis,vis+maxn,0);
scanf("%d%d",&start,&end1);
minline = inf;
mincnt = inf;
temp.clear();
temp.push_back(node{start,0});
vis[start] = 1;
DFS(start,0,0,0);
printf("%d\n",mincnt);
int pretransfer = start;
int preline = 0;
for(int j = 1;j<path.size();j++)
{
if(path[j].line!=preline)
{
if(preline!=0)
{
printf("Take Line#%d from %04d to %04d.\n",preline,pretransfer,path[j-1].indice);
}
preline = path[j].line;
pretransfer = path[j-1].indice;
}
}
printf("Take Line#%d from %04d to %04d.\n",preline,pretransfer,end1);
}
return 0;
}
反思:深度遍历不熟悉。对于边权,当顶点比较多的时候,用邻接矩阵太大。可以用邻接表存边,用一个unordered_map存边权。也可以用结构体用链表存边权。会比较复杂。第一遍写的时候第一个第三个测试点一直不过。找不出原因,后来重新写了一遍,通过,反思,往往一些不知道为什么的错误,往往来自于逻辑思路不清晰,所以,会出现意外的小错误。这种比较难处理。所以要在源头上有清晰的思路,这样按照条理写下来,就不会有问题。往往摸棱两可的时候,写下来。会出问题。多捋捋思路。