PAT甲级1131. Subway Map

PAT甲级1131. Subway Map

题意:

在大城市,地铁系统对访客总是看起来很复杂。给你一些感觉,下图显示了北京地铁的地图。现在你应该帮助人们掌握你的电脑技能!鉴于您的用户的起始位置,您的任务是找到他/她目的地的最快方式。
输入规格:

每个输入文件包含一个测试用例。对于每种情况,第一行包含正整数N(<= 100),地铁线数。然后N行跟随,第i(i = 1,...,N)行以格式描述第i条地铁线:

M S [1] S [2] ... S [M]

其中M(<= 100)是停止次数,S [i](i = 1,...)
M)是沿线的指标(指数是从0000到9999的4位数字)。确保车站以正确的顺序给出 - 即火车在S [i]和S [i + 1](i = 1,...,M-1)之间不间断地行驶。

注意:可以有循环,
循环(没有火车从S开始,S停止,不经过另一个站)。每个站间隔属于唯一的地铁线。虽然这些线路可能在某些车站(所谓的“转运站”)相互交叉,但是任何车站都不能超过5条线路。

在描述地铁后,
给出另一个正整数K(<= 10)。然后按K行,每个给出您的用户的查询:两个索引分别作为起始站和目的地。

下图显示了示例图。
注意:保证所有站点都可以访问,所有查询都包含合法站号。

输出规格:

对于每个查询,首先在一行中打印最少的停靠点数。那么你应该以友好的格式显示最佳路径,如下所示:

从X1到S2的线#X1。
从S2到S3取第X2行

......
其中Xi是线数,Si是站指数。注意事项:除了起点和终点站外,只能印制转运站。

如果最快的路径不是唯一的,输出最小数量的传输,这被保证是唯一的。

思路:

最短路。我一开始用Dijkstra + dfs除了最后一个超时,其他都是0ms。后来不用Dijkstra,只用dfs就过了。奇怪的是Dijkstra + dfs居然会慢一些 = =。。不过小数据Dijkstra + dfs 都是0ms 但是最后大数据。好像只用dfs貌似会快一些,但是小数据没有Dijkstra + dfs理想。。
这题问题就是加了一线路吧问题复杂化了。我用vector储存next站台。然后用的是pair<int,int>储存下一个站台的id和线路。一开始我吧线路的属性放到站台,这样的话transfer的线路属性就不知道是什么了。所以线路的属性在边上。就放到next里,用pair保存。
其实还有一种方法就是用5位数保存。前面四位数保存id,第一位保存线路。因为题目中数据范围已知,到时候只用求余等操作就可以了。

ac代码:

C++

// pat1131.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<queue>
#include<vector>
#include<cstring>
#include<stdio.h>
#include<map>
#include<cmath>
#include<unordered_map>
#include<unordered_set>

using namespace std;

int starting, ending;

struct Station
{
	int val;
	vector<pair<int,int>> next;
};

Station st[10001];
int visit[10001];
int len[10001];
unordered_set<int> have;

void Dijkstra()
{
	memset(visit, 0, sizeof(visit));
	memset(len, -1, sizeof(len));

	int now = -1;
	unordered_set<int>::iterator it;
	len[starting] = 0;
	while (1)
	{
		now = -1;
		for (it = have.begin(); it != have.end(); it++)
		{
			if (!visit[*it] && len[*it] != -1 && (now == -1 || len[*it] < len[now])) now = *it;
		}
		if (now == -1 || now == ending) break;
		visit[now] = 1;
		for (int i = 0; i < st[now].next.size(); i++)
		{
			if (!visit[st[now].next[i].first] && (len[st[now].next[i].first] == -1 || len[st[now].next[i].first] > len[now] + 1))
			{
				len[st[now].next[i].first] = len[now] + 1;
			}
		}
	}
}

struct way
{
	int s;
	int e;
	int line;
	way(int x, int y, int z) : s(x) , e(y) , line(z) {}
};

vector<vector<way> > res;
vector<way> path;
int min_cnt;

void dfs(int now,int cur_cnt, int last,vector<way>& mytemp, int line)
{
	//if (cur_cnt > len[ending]) return;
	if (cur_cnt > min_cnt) return;
	//if (now == ending && cur_cnt == len[ending])
	if (now == ending && cur_cnt <= min_cnt)
	{
		mytemp.push_back(way(last, ending, line));
		if (res.empty() || (mytemp.size() < res[0].size() && cur_cnt == min_cnt) || cur_cnt < min_cnt)
		{
			res.clear();
			res.push_back(mytemp);
		}
		min_cnt = cur_cnt;
		mytemp.pop_back();
		return;
	}

	visit[now] = 1;

	for (int i = 0; i < st[now].next.size(); i++)
	{
		if (!visit[st[now].next[i].first])
		{
			if (st[now].next[i].second != line && now != last)
			{
				mytemp.push_back(way(last, now, line));
				dfs(st[now].next[i].first, cur_cnt + 1, now, mytemp, st[now].next[i].second);
				mytemp.pop_back();
			}
			else
			{
				dfs(st[now].next[i].first, cur_cnt + 1, last, mytemp, st[now].next[i].second);
			}
			visit[st[now].next[i].first] = 0;
		}
	}

}


int main()
{
	int n, m, id, last;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		scanf("%d", &m);
		for(int j = 0; j < m; j++)
		{
			scanf("%d", &id);
			have.insert(id);
			st[id].val = id;
			
			if (j > 0)
			{
				st[id].next.push_back(make_pair(last,i));
				st[last].next.push_back(make_pair(id, i));
			}
			last = id;
		}
	}

	
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
	{
		scanf("%d %d", &starting, &ending);

		//Dijkstra();
		min_cnt = have.size();
		memset(visit, 0, sizeof(visit));
		vector<way> temp;
		res.clear();
		dfs(starting,0,starting,temp,1);


		//printf("%d\n", len[ending]);
		printf("%d\n", min_cnt);
		for (int i = 0; i < res[0].size(); i++)
		{
			printf("Take Line#%d from %04d to %04d.\n", res[0][i].line,res[0][i].s,res[0][i].e);
		}
	}
    return 0;
}


posted on 2017-08-14 10:29  炮二平五  阅读(1196)  评论(0编辑  收藏  举报

导航