zoukankan      html  css  js  c++  java
  • A1131 Subway Map (30分)

    一、技术总结

    1. 题目意思是,给定N条地铁线,然后可能线路与线路之间会有转换站,给出,出发点和目的点,要求输出乘坐的站数以及在每条线路上的转换点,包括出发点和目的点。具体可以查看例子。
    2. 我们使用vector用来存储地图,unordered_map<int, int>类型的line来进行存储站点与站点之间所属的线路(就是几号线的意思),因为站点编号为4位,所以采用编号idx10000+id,然后后一个使用线路编号。
    3. 采用dfs深度搜索的办法,如果是当node==end1,同时可能出现乘坐站点数量cnt比之前少或则站点数量一样,但是转换线路较少(这里使用transferCnt函数来判断),那么就更新数据。最后node==end1,return。遍历过程中,从第一个结点开始,遍历它能够到达的结点,如果visit为0,代表该结点没有被访问过,然后进入置为1,将该结点插入tempPath路径中。然后dfs递归,传参时结点数量加一,记得要重新将该结点置为0,然后将该结点弹出路径,因为在其他路径中可能会使用到该结点。
    4. transferCnt函数,该函数作用就是用来计算已经生成的路径中换线路的次数。这时line变量就发挥作用了,初始化线路数量cnt = -1, preLine = 0代表当前线路的编号,然后从第二个结点开始遍历。初始化cnt=-1,是因为开始为了获取第一条线路的编号,之后如果有与第一条线路不同,代表转线一次,仔细理解一下。
    5. 最后就是输出结果了,首先打印乘坐站点的数量,直接输出minCnt问题不大;然后是输出线路的问题,这里其实跟transferCnt函数的思想是一致的,首先初始化preLine=0,即不知道线路,要先去获取线路,pretransfer=start,这是为第一条线路的输出做准备。也是从第二个结点开始遍历,如果发现线路不同,同时还要判断一下是否preLine=0,因为第一次线路的改变是为了获取真实线路,没有意义。只有当第二次出现preLine不同时,代表真正意义上的转线,需要进行输出结果,同时更新preLine为新线路的编号,也要将pretransfer赋值为转换站点的编号,作为下一条线路的开始站点。
    6. 要慢慢去理解,这一题一位我将=敲成了==导致出现段错误,看了一晚上,也不知道问题在哪,还是要小心啊,不过这也算是积累经验。

    二、参考代码

    #include<iostream>
    #include<vector>
    #include<unordered_map>
    using namespace std;
    vector<vector<int> > v(10000);
    int visit[10000], minCnt, minTransfer, start, endlt;
    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 == endlt && (cnt < minCnt || (cnt == minCnt && transferCnt(tempPath) < minTransfer))){
    		minCnt = cnt;
    		minTransfer = transferCnt(tempPath);
    		path = tempPath;
    	}
    	if(node == endlt) 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, &endlt);
    		minCnt = 99999, minTransfer = 99999;
    		tempPath.clear();
    		tempPath.push_back(start);
    		visit[start] = 1;
    		dfs(start, 0);
    		visit[start] = 0;
    		printf("%d
    ", 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.
    ", 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.
    ", preLine, preTransfer, endlt);
    	}
    	return 0;
    }
    
    作者:睿晞
    身处这个阶段的时候,一定要好好珍惜,这是我们唯一能做的,求学,钻研,为人,处事,交友……无一不是如此。
    劝君莫惜金缕衣,劝君惜取少年时。花开堪折直须折,莫待无花空折枝。
    曾有一个业界大牛说过这样一段话,送给大家:   “华人在计算机视觉领域的研究水平越来越高,这是非常振奋人心的事。我们中国错过了工业革命,错过了电气革命,信息革命也只是跟随状态。但人工智能的革命,我们跟世界上的领先国家是并肩往前跑的。能身处这个时代浪潮之中,做一番伟大的事业,经常激动的夜不能寐。”
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
  • 相关阅读:
    POJ 1953 World Cup Noise
    POJ 1995 Raising Modulo Numbers (快速幂取余)
    poj 1256 Anagram
    POJ 1218 THE DRUNK JAILER
    POJ 1316 Self Numbers
    POJ 1663 Number Steps
    POJ 1664 放苹果
    如何查看DIV被设置什么CSS样式
    独行DIV自适应宽度布局CSS实例与扩大应用范围
    python 从入门到精通教程一:[1]Hello,world!
  • 原文地址:https://www.cnblogs.com/tsruixi/p/13090237.html
Copyright © 2011-2022 走看看