需二刷
注意一下输出格式!!!!!%04d这他娘的就是个坑!!!
#include<iostream>
#include<vector>
#include<unordered_map>
using namespace std;
vector<int> path,tempath,v[10009];
unordered_map<int,int> line;
int anscnt,anstcnt, start,end1, visit[10009]={0};
// 如果全局变量 与函数中参数的声明变量相同会出现问题(注意)
//以后统一格式(注意)最上面写函数用到的,下面主函数写声明看看能不能写到一行
//目的收集最小
//还没处理是环的情况
//tcnt -1 换乘站数
int transfer(vector<int> a,int tcnt)
{ int pre=-1;
for(int i=1;i<a.size();i++)
{
if(line[a[i-1]*10000+a[i] ]!=pre) tcnt++;
pre=line[a[i-1]*10000+a[i]];
}
return tcnt;
}
//root结点序号 cnt 经过站数 0
void dfs(int root,int cnt,int end)
{
//end
if(root==end)
{ int tcnt=transfer(tempath,-1);
if(cnt<anscnt||cnt==anscnt&&tcnt<anstcnt)
{ anscnt=cnt;
anstcnt=tcnt;
path=tempath;
}
//不能clear,之前的数据还有用,只能将当前的结点删掉(注意)
//tempath.clear();
return;
}
//一个小规律大部分是保留参数值括号里的(注意)
for(int i=0;i<v[root].size();i++)
{ //闭圈
if(visit[v[root][i]]==0){
//直接在同一层干完,下面直接去判断不要再留给下面 (注意)
visit[v[root][i] ]=1;
tempath.push_back(v[root][i]);
dfs(v[root][i],cnt+1,end);
//只有纳入其中的才能赋值为/*1(注意)
visit[v[root][i]]=0;
//与树的dfs的区别是,树是所有节点全入只是一个顺序问题,没有出,而路径问题有进有出,所以不能直接clear,要让他在这个基础上弹出一个(注意)
tempath.pop_back();
}
}
}
int main()
{ //m:路线数
int m,tempk,temppp,tempq;
cin>>m;
int ll=1;
for(int i=0;i<m;i++)
{
cin>>tempk;
vector<int> tempp;
//图与路线存储完毕
for(int i=0;i<tempk;i++)
{
cin>>temppp;
tempp.push_back(temppp);
}
for(int i=1;i<tempk;i++)
{ //用邻接表存储路径
v[tempp[i-1]].push_back(tempp[i]);
v[tempp[i]].push_back(tempp[i-1]);
//存储路线号
line[10000*tempp[i]+tempp[i-1]]=line[10000*tempp[i-1]+tempp[i]]= ll;
}
ll++;
}
cin>>tempq;
for(int i=0;i<tempq;i++)
{
//前面已经声明此处只需改变值即可不要再重复声明(注意)
//这里前面不能再加int 否则本来是全局变量就会降为局部变量(注意)
anscnt=99999,anstcnt=99999;
cin>>start>>end1;
//现在外面把第一次处理了(注意)
tempath.clear();
tempath.push_back(start);
visit[start]=1;
dfs(start,0,end1);
visit[start]=0;
printf("%d\n",anscnt);
int pre=0, pretransfer=start;
for(int j=1;j<path.size();j++)
if(line[path[j-1]*10000+path[j]]!=pre){
if(pre!=0)printf("Take Line#%d from %04d to %04d.\n",pre,pretransfer,path[j-1]);
pre=line[path[j-1]*10000+path[j]];
//忘记写改变起点 换的点应该是path[i-1](注意)
pretransfer=path[j-1];
}
printf("Take Line#%d from %04d to %04d.\n",pre,pretransfer,end1);
//printf("Take Line#%d from %04d to %04d.\n", preLine, preTransfer, end1);
}
/*for (int i = 0; i < tempq; i++) {
scanf("%d%d", &start, &end1);
anscnt = 99999, anstcnt = 99999;
tempath.clear();
tempath.push_back(start);
visit[start] = 1;
dfs(start, 0,end1);
visit[start] = 0;
printf("%d\n", anscnt);
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;
}
总结
1.%04d与%4d的唯一区别就是左边填充0。 看题目输出按格式,如果只是输出那个数前面没有填0就是答案错误
其他各种键代码注释,几乎错了一遍,收获颇多
2.要想闭环内部在路径中的要做标记,出来了标记就要去了。和数最大的区别,树不会成环不需标记为什么没有回退pop这一个
3.存储道路的属性 hash如路名10000x啥留出下一个结点的位置
英语:
问题
总结DFS对于最短路径问题的模板
树打印从根节点到叶节点有没有退出pop这一步?