pat-1131

需二刷 

注意一下输出格式!!!!!%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对于最短路径问题的模板

扫描二维码关注公众号,回复: 12379293 查看本文章

树打印从根节点到叶节点有没有退出pop这一步? 

猜你喜欢

转载自blog.csdn.net/m0_45359314/article/details/112797838
今日推荐