A1134 Vertex Cover (25分)

1.原先的思路:导致两个例子运行超时

#include<cstdio>
#include<string>
#include<iostream>
#include<vector>
#include <algorithm>//fill()在里面 
#include <cmath>
#include<queue>
#include<unordered_set>
#include<set> 
#include <cstdlib>//貌似是free,malloc等函数的头文件 
using namespace std;

//A1134  
//图中的每一条边至少连接其中的一个节点 
//判断给出的节点集合是不是vertex cover 
const int INF=1e9; //fill(map[0],map[0]+maxn*maxn,INF); 
const int maxn=100010;
struct node{//边的结构 
	int a,b;
}temp;
vector<node> edge;
vector<int> vertex;
int main(){
	int n,m;
	scanf("%d%d",&n,&m); 
	//n:节点的数量 m:边的数量
	while(m--){
		//给出边的头尾索引
		 scanf("%d%d",&temp.a,&temp.b);
		 //每条边的的两个节点至少有一个节点能在vertex cover里面找到 
		 edge.push_back(temp);
	} 
	int k,nv;
	scanf("%d",&k);
	while(k--){
		scanf("%d",&nv);
		vertex.clear();//记得清空 
		int num;
		while(nv--){
			scanf("%d",&num);
			vertex.push_back(num);
		}
		//遍历每一条边的节点信息,看是否能在vertex里面找到
		int flag=1;
//这种思路会运行超时,采用map才行
		for(int i=0;i<edge.size();i++){
			int v1=edge[i].a;
			int v2=edge[i].b;
			vector<int>::iterator it1,it2;
			it1=find(vertex.begin(),vertex.end(),v1);
			it2=find(vertex.begin(),vertex.end(),v2);
			if(it1!=vertex.end()||it2!=vertex.end()){
				//其中一个在vertex中找到即可 
			}else{
				printf("No\n");
				flag=0;
				break;
			}	
		} 
		if(flag==1){
			printf("Yes\n");
		}
	}
	return 0;
} 

2.使用map映射来提高速度

#include<cstdio>
#include<string>
#include<iostream>
#include<vector>
#include <algorithm>//fill()在里面 
#include <cmath>
#include<queue>
#include<unordered_set>
#include<set> 
#include <cstdlib>//貌似是free,malloc等函数的头文件 
using namespace std;

//A1134  
//图中的每一条边至少连接其中的一个节点 
//判断给出的节点集合是不是vertex cover 
const int INF=1e9; //fill(map[0],map[0]+maxn*maxn,INF); 
const int maxn=10010;
struct node{//边的结构 
	int a,b;
}temp;
vector<int> map[maxn];//用作map的映射,索引是点:map[i].push_back(edge1):在i点中插入和其相邻的边的索引 
int main(){
	int n,m;
	scanf("%d%d",&n,&m); 
	//n:节点的数量 m:边的数量
	int visit[m+1]={0};
//边是否被访问过:后面查询的时候只要遍历完所有节点之后:能把所有边都visit,那么就说明这个节点是Yes 
	for(int i=0;i<m;i++){
//边的索引是i
		scanf("%d%d",&temp.a,&temp.b);
		map[temp.a].push_back(i);
		map[temp.b].push_back(i);
	}

	int k,nv;
	scanf("%d",&k);
	while(k--){
		scanf("%d",&nv); 
		fill(visit,visit+m+1,0);//visit重新置零 
		int num;
		while(nv--){
			scanf("%d",&num);
			for(int i=0;i<map[num].size();i++){
				int e=map[num][i];
				if(!visit[e])visit[e]=1;
			}
		}
		//遍历visit进行检查
		int count=0;
		for(int i=0;i<m;i++){
			if(visit[i]==1)count++;
		} 
		if(count==m)printf("Yes\n");
		else printf("No\n");
	
	}
	return 0;
} 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值