题目描述
1131 Subway Map (30分)
给一张map,求map中某点到某点的最短距离。
知识点
图的DFS
我的实现
码前思考
我第一次写的时候用的是Dijkstra,结果超时了,所以一直都没改正。
这一次写的时候参考了柳神的代码,使用了DFS的方式来求解问题。很奇怪的是,DFS这么暴力的方法,居然也可以做到不超时,实在是令人匪夷所思!!!
代码实现
#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
using namespace std;
vector<vector<int>> v(10000);
int visit[10000],minCnt,minTransfer,start,end1;
unordered_map<int,int> line;
vector<int> path,tempPath;
//用于求解换站的次数
int transferCnt(vector<int> a){
int cnt=-1,preLine=0;
for(int i=1;i<a.size();i++){
if(line[a[i-1]*10000+a[i]] != preLine) cnt++;
preLine = line[a[i-1]*10000+a[i]];
}
return cnt;
}
//用于暴力求解到达终点的路径
void dfs(int node,int cnt){
if(node==end1&&(cnt<minCnt||(cnt==minCnt&&transferCnt(tempPath)<minTransfer))){
minCnt=cnt;
minTransfer=transferCnt(tempPath);
path=tempPath;
}
if(node==end1) return;
for(int i=0;i<v[node].size();i++){
if(visit[v[node][i]]==0){
visit[v[node][i]]=1;//目的是为了不构成环路!
tempPath.push_back(v[node][i]);
dfs(v[node][i],cnt+1);
visit[v[node][i]]=0;
tempPath.pop_back();
}
}
}
int main(){
int n,m,k,pre,temp;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d%d",&m,&pre);
for(int j=1;j<m;j++){
scanf("%d",&temp);
v[pre].push_back(temp);
v[temp].push_back(pre);
line[pre*10000+temp] = line[temp*10000+pre] = i+1;
pre=temp;
}
}
scanf("%d",&k);
for(int i=0;i<k;i++){
scanf("%d%d",&start,&end1);
minCnt=99999,minTransfer=99999;
tempPath.clear();
tempPath.push_back(start);
visit[start]=1;
dfs(start,0);
visit[start]=0;
printf("%d\n",minCnt);
int preLine=0,preTransfer=start;
for(int j=1;j<path.size();j++){
if(line[path[j-1]*10000+path[j]] != preLine){
if(preLine!=0) printf("Take Line#%d from %04d to %04d.\n",preLine,preTransfer,path[j-1]);
preLine = line[path[j-1]*10000+path[j]];
preTransfer = path[j-1];
}
}
printf("Take Line#%d from %04d to %04d.\n", preLine, preTransfer, end1);
}
return 0;
}
码后反思
(ง •_•)ง这道题目我是抄的代码,自己其实没有手动敲。