PAT A1149 Dangerous Goods Packaging【稀疏图考虑边】⭐⭐⭐⭐⭐

37 篇文章 1 订阅
15 篇文章 0 订阅

题目描述

在这里插入图片描述

知识点

实现

码前实现

  1. 这道题我写错了,我一开始是这样写的:
    在这里插入图片描述
  2. 上面的分析确实有道理,如果一直两两点比较,那么就是组合数了,时间复杂度变成了 1 0 3 × 1 0 3 = 1 0 6 10^3 \times 10^3 = 10^6 103×103=106。但是,如果只是遍历边的话,那么最多也只有 2 × 1 0 4 2 \times 10^4 2×104的时间复杂度!
  3. 因此,每次都是扫描该点的所有不匹配点是否出现在了之前的数字中。

代码实现

#include "bits/stdc++.h"
using namespace std;

const int maxn = 1e5+10;

unordered_map<int,vector<int> > mp; 
int n;
int m;

//用于标记是否在集合之中 
bool vis[maxn];

int main(){
	scanf("%d %d",&n,&m);
	for(int i=0;i<n;i++){
		int u;
		int v;
		scanf("%d %d",&u,&v);
		mp[u].push_back(v);
		mp[v].push_back(u); 
	}
	for(int i=0;i<m;i++){
		fill(vis,vis+maxn,false); 
		int k;
		scanf("%d",&k);
		//不使用全部输入 
		bool flag = true;
		for(int j=0;j<k&&flag;j++){
			int u;
			scanf("%d",&u);
			if(mp.count(u)){
				for(int l=0;l<mp[u].size();l++){
					int v = mp[u][l];
					if(vis[v] == true){
						flag = false;
						break;
					}				
				}			
			}
			vis[u] = true;
		}
		string tmp;
		getline(cin,tmp);
		
		if(flag == true){
			printf("Yes\n");
		}else{
			printf("No\n");
		}
	}
	return 0;
} 

码后反思

  1. 对于这种题,一定要看是针对点与点进行操作,还是针对边进行操作。他们的时间复杂度通常是不一样的。
  2. 很明显这里边的数量是少的,而点的数量是多的。相当于是一个稀疏图,那么使用边最好啊!!!就跟最小生成树一个思路啊!!!

二刷代码

我就是一头猪,怎么也教不会,这次又超时了,原因还是老原因,还是遍历所有物品判断了。。。
这次参考了柳神的代码:

#include <iostream>
#include <vector>
#include <map>
using namespace std;

int main(){
	int n,k,t1,t2;
	map<int,vector<int> > m;
	scanf("%d%d",&n,&k);
	for(int i=0;i<n;i++){
		scanf("%d%d",&t1,&t2);
		m[t1].push_back(t2);
		m[t2].push_back(t1);
	}
	while(k--){
		int cnt,flag=0,a[100000]={0};
		scanf("%d",&cnt);
		vector<int> v(cnt);
		for(int i=0;i<cnt;i++){
			scanf("%d",&v[i]);
			a[v[i]] = 1;
		}
		for(int i=0;i<v.size();i++){
			for(int j=0;j<m[v[i]].size();j++){
				if(a[m[v[i]][j]] == 1) flag = 1;
			}
		}
		printf("%s\n",flag?"No":"Yes");
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值