当前位置: 首页 > 工具软件 > Subway > 使用案例 >

1131 Subway Map (30分)

勾海超
2023-12-01

这算比较难的一个题了,主要有几个细节需要注意:

①:关于某条线路中转站数量的计算:

不可以直接通过计算所经过的点是否为中转站,因为即使这个点是中转站,但是在某条线路上仍可能是不需要中转。

②:关于输出,切记要按4位输出,不然无法过测试点2

附本人代码:

#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<unordered_map>
#include<string.h>
#include<algorithm>
using namespace std;
int line[10001][10001], s, d, maxsum, maxctr;
bool tran[10010], flag[10010];
map<int, vector<int>>Ma;
vector<int>tmp, ans;
void dfs(int pre,int now, int sum,int lin,int ctr) {
	tmp.push_back(now);
	if (pre != now) {
		if (lin != line[pre][now]) {//及其关键,统计改变线路 的点
			ctr++;		//注意不可以直接统计该点是否为中专点,因为即使这里可以中专,该路线可能在这个点处不中专。
			lin = line[pre][now];
		}
	}
	if (now == d) {
		if (sum < maxsum) {
			maxsum = sum;
			ans = tmp;
			maxctr = ctr;
		}
		else if (sum == maxsum && ctr < maxctr) {
			ans = tmp;
			maxctr = ctr;
		}
		tmp.pop_back();
		return;
	}
	flag[now] = true;
	for (int i = 0; i < Ma[now].size(); i++) {
		if (!flag[Ma[now][i]])dfs(now,Ma[now][i], sum + 1,lin,ctr);
	}
	flag[now] = false;
	tmp.pop_back();
}
int main() {
	int N, num, val, M;
	scanf("%d", &N);
	for (int i = 1; i <=N; i++) {
		scanf("%d", &num);
		int pre = -1;
		for (int j = 0; j < num; j++) {
			scanf("%d", &val);
			if (pre != -1) {
				line[val][pre] = line[pre][val] = i;//保存两个点之间的地铁线编号
				Ma[val].push_back(pre);//与他相连的点个数
				Ma[pre].push_back(val);//同上
			}
			pre = val;
		}
	}
	scanf("%d", &M);
	for (int i = 0; i < M; i++) {
		scanf("%d%d", &s, &d);
		maxsum = 9999;
		maxctr = 9999;
		dfs(s,s,0,0,0);
		printf("%d\n", ans.size() - 1);
		int head = ans[0], lin = line[ans[0]][ans[1]];
		for (int i = 1; i < ans.size(); i++) {
			if (line[ans[i - 1]][ans[i]] != lin) {
				printf("Take Line#%d from %04d to %04d.\n",lin,head,ans[i-1]);
				lin = line[ans[i - 1]][ans[i]];
				head = ans[i - 1];
			}
		}
		printf("Take Line#%d from %04d to %04d.\n", lin, head, ans.back());
	}
	return 0;
}
 类似资料: