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 1466 Girls and Boys
    poj 1486 Sorting Slides
    poj 2112 Optimal Milking
    poj 1274 The Perfect Stall
    SHoj 420 购买装备
    poj 2987 Firing
    SHoj A序列
    FOJ Problem 2271 X
    XidianOJ 1028 数字工程
    XidianOJ 1030 三数和
  • 原文地址:https://www.cnblogs.com/tsruixi/p/13090237.html
Copyright © 2011-2022 走看看