PAT 1150 C++ 版

版权声明:如若转载,请联系作者。 https://blog.csdn.net/liu16659/article/details/86769237

PAT 1150 C++

1.题意

给出一个无向图的顶点,边信息。然后给出一系列的访问序列,判断这些序列属于哪种序列。然后给出最短的路径信息。
路径类型有:

  • TS simple cycle if it is a simple cycle that visits every city;
  • TS cycle if it is a cycle that visits every city, but not a simple cycle;
  • Not a TS cycle if it is NOT a cycle that visits every city.

2.分析

题很简单,但是做起来很麻烦。

  • 使用二维数组存储 边信息
  • 使用一维数组存储节点是否访问信息
  • 使用一维数组存储遍历的节点信息
  • 使用map存储最后的结果信息,找出最短路径

3.代码

#include<cstdio>
#include<iostream>
#include<cstring>
#include<map>
#define maxn 20005

using namespace std;


int main(){
	int isVisit[maxn];
	int edge[205][205];
	int N,M;//N 是城市数; M是边数 
	cin >> N >> M;
	int i ,j;
	int ver1,ver2,a;
	
	for(i = 0;i< 205;i++){
		for(j = 0;j< 205;j++)
			edge[i][j] = -1;
	}
	
	for(i = 0;i< M ;i++){
		cin >> ver1>> ver2 >> a;
		edge[ver1][ver2] = a;
		edge[ver2][ver1] = a;
	}
	
	map<int,int> res;//保存最后的筛选结果
	
	int queryNum;
	cin >> queryNum;	
	for(i = 0;i< queryNum;i++){
		int num;//表示当前访问城市的个数 
		int array[maxn];//用于存储查询的序列 
		cin  >> num;
		int dis = 0;//节点之间的总距离 
		int pre;//表示上一个节点 
		int flag = 0;

		memset(isVisit,0,sizeof(isVisit));//初始化所有的城市节点访问信息				
		for(j = 0;j< num;j++){
			cin >> array[j]; 
			isVisit[array[j]] = 1;//说明这个节点访问到了 
			
			if(j!=0){//如果当前的节点不是0 
				if(edge[pre][array[j]] != -1){
					dis += edge[pre][array[j]];//求出总和 	
				}
				else{//说明两个城市不存在线路 
					flag = 2; 					
				}				
			} 
			pre = array[j];
		}		
	 
	 	if(flag == 2){
	 		cout << "Path " << i+1 <<": NA (Not a TS cycle)"<<"\n";
	 		continue;
		}
		
		for(j = 1;j <= N;j++ ){
			if(isVisit[j] == 0){
				flag = 1;//表示城市访问不全 
				break; 
			}			 
		} 
		if(j <= N || (array[0] != array[num-1])){//说明不是 cycle
			cout << "Path " << i+1 <<": "<<dis<<" (Not a TS cycle)"<<"\n";					
		}
		else{
			if(num == N + 1){//说明是一个 TS simple cycle 
				cout << "Path " << i+1 <<": "<<dis<<" (TS simple cycle)"<<"\n";				
			}
			else{//说明有重复访问城市 
				cout << "Path " << i+1 <<": "<< dis <<" (TS cycle)"<<"\n";
			}			
			res[i+1]= dis;
		}			 				
	} 
	int minDis = 999999;//不一定是最大值 
	int minIndex;
	for(map<int,int>::iterator it = res.begin();it!=res.end();it++){
		if(minDis > it->second ){
			minDis = it->second;
			minIndex = it->first;
		}
	}
	cout << "Shortest Dist("<<minIndex << ") = "<<minDis<<"\n";
} 

4.测试用例

6 10
6 2 1
3 4 1
1 5 1
2 5 1
3 1 8
4 1 6
1 6 1
6 3 1
1 2 1
4 5 1
7
7 5 1 4 3 6 2 5
7 6 1 3 4 5 2 6
6 5 1 4 3 6 2
7 6 3 2 5 4 1 6
9 6 2 1 6 3 4 5 2 6
4 1 2 5 1
7 6 1 2 5 4 3 1

5.执行结果

一遍AC。

6.坑点

6.1 错误的地方break

为了让代码更加简洁,我本想在flag=2之后添加break。但是后来却发现了错误。

if(j!=0){//如果当前的节点不是0 
	if(edge[pre][array[j]] != -1){
		dis += edge[pre][array[j]];//求出总和 	
	}
	else{//说明两个城市不存在线路 
		flag = 2; 
		//break;记住这里不能break,否则会造成错误答案 
	}				
} 

这里错误的原因是:那一行的输入还没有结束,结果你却结束了。导致输入数据出错,从而导致执行结果出错。【因为这里的输入和处理是在同一个for循环中处理的】

猜你喜欢

转载自blog.csdn.net/liu16659/article/details/86769237