PAT 1134 C++

1.题意

输入:给出一个无向图的边节点信息;给出数组待查询顶点的集合
让你判断图中的任一条边的顶点是否都在这个顶点的集合中?如果都在则称为vertex cover,否则不是。

2.分析

  • 暴力求解
    直接根据输入新建一个结构体数组,其中保留的是每条边left,right左右两个节点,以及一个访问标志位。在输入节点集合之后,使用双重循环遍历一遍,表示边的访问信息。最后再使用一个循环,找出是否存在未访问的边,如果有,则输出No,否则输出Yes。

3.代码

  • 暴力求解
#include<cstdio>
#include<iostream>
using namespace std;

struct edge{
	int left,right;//一条边的左右两个顶点
	int visit = 0 ;//标识这条边是否访问过,初始值为0 
};

edge e[10005]; 

int main(){
	int N,M;
	scanf("%d %d",&N,&M);
	int i,j,x;
	for(i = 0;i< M;i++){
		scanf("%d%d",&e[i].left,&e[i].right);
	}
	int K;//待查询数 
	scanf("%d",&K);
	int verNum;//表示待查询的顶点集合数 
	int verSet[10005]; 
	for(i = 0;i< K;i++){
		scanf("%d",&verNum);	
		for(j = 0;j< verNum;j++){
			scanf("%d",&verSet[j]);//输入待查询的每个vertex 			
		}
		
		//开始进行处理
		//外层循环代表的是 
		for( x = 0; x < M; x++ ){
			for(j = 0;j < verNum;j++){
				if(e[x].left == verSet[j] || e[x].right == verSet[j]) {
					e[x].visit = 1;//置为1 
				}
			}
		}
		
		for( x = 0;x < M ;x++){
			if(e[x].visit == 0){//代表仍然有不满足的情况 
				break;
			}
			e[x].visit = 0;//reset 
		}
		if(x == M) cout <<"Yes"<<endl;
		else cout<<"No"<<endl;		
	} 
}

但是这个代码的执行结果是存在两组 运行超时 的用例。显然不是最优的解决办法。

4.执行结果

PAT 1134 C++ 版_# PAT

5.优化记录

在使用数组碰到运行超时的问题时,就需要考虑到set。这真是个好东西。解题思想没有变化,只不过是将int verSet[10005]; 替换成set<int> verSet;然后将相应的数组操作替换成 set 操作即可。得到的代码如下:

#include<cstdio>
#include<iostream>
#include<set>
using namespace std;

struct edge{
	int left,right;//一条边的左右两个顶点 
	int isVisit = 0;//表示是否访问过 
};
 
edge e[10005];  

int main(){
	int N,M;
	scanf("%d %d",&N,&M);
	int i,j,x;
	int left,right; 
	for(i = 0;i< M;i++){
		scanf("%d%d",&e[i].left,&e[i].right);	
	}
	int K;//待查询数 
	scanf("%d",&K);
	int verNum;//表示待查询的顶点集合数 
	set<int> verSet; //待查询顶点集 
	int vertex;//每个顶点 
	for(i = 0;i< K;i++){
		scanf("%d",&verNum);	
		for(j = 0;j< verNum;j++){
			scanf("%d",&vertex);//输入待查询的每个vertex
			verSet.insert(vertex);//插入到set中 
		}
					
		//开始进行处理
		for( x= 0; x<M;x++ ){
			if(verSet.find(e[x].left)==verSet.end() 
			&& verSet.find(e[x].right)==verSet.end() ){				
				break;
			}
		}
		
		if(x == M) cout <<"Yes"<<endl;
		else cout<<"No"<<endl;
		
		verSet.clear();//clear set		
	} 
}
  • 测试用例
10 11
8 7
6 8
4 5
8 4
8 1
1 2
1 4
9 8
9 1
1 0
2 4
5
4 0 3 8 4
6 6 1 7 5 4 9
3 1 8 4
2 2 8
7 9 8 7 6 5 4 2
  • 执行结果
    PAT 1134 C++ 版_# PAT_02
    一遍AC。