A1134
个人思路
本题考查图的存储访问,再次基础上考查散列(STL)
题意
给出一个图和顶点集合,如果顶点能覆盖图中所有的边,称其为vertex cover
思路
- 数据结构使用两个map,edges存储原图中所有的边的hash值,vis记录点集能覆盖到的边;
- edges中将所有边初始化为1,将edges赋值给vis进行初始化,查询过程中覆盖到的边为2
- 当edges[ehash] == 1 && vis[ehash] == 1说明这条边未被覆盖,输出No(ehash表示边的hash值)
- 运用散列的思想将每条边转换为唯一的hash值,即u * 10000 + v,1w为数据量,由于v,u不相同,因此可保证散列不会发生冲突。
注意
由于数据量在1w,不适合用邻接矩阵。
个人思路代码
#include <bits/stdc++.h>
using namespace std;
const int maxn = 10005;
const int h = 10000;
int N, M;
vector<int> G[10005];
unordered_map<int, int> edges;
unordered_map<int, int> vis;
int main(int argc, char *argv[]) {
scanf("%d%d", &N, &M);
for(int i = 0; i < M; ++i)
{
int u, v;
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
edges[u * h + v] = 1;//1:为有效边
edges[v * h + u] = 1;
}
int K;
scanf("%d", &K);
while(K--)
{
vis = edges;//初始化vis
int num;
scanf("%d", &num);
for(int i = 0; i < num; ++i)
{
int u;
scanf("%d", &u);
for(int v = 0; v < G[u].size(); ++v)
{
int next = G[u][v];
vis[u * h + next] = vis[next * h + u] = 2;
}
}
bool flag = true;//标记是否覆盖
for(auto it = edges.begin(); it != edges.end(); ++it)//自动指针代替迭代器
{
int key = it->first;
int value = it->second;
if(edges[key] == 1 && vis[key] == 1)//当前边未被覆盖
{
flag = false;
break;
}
}
if(flag == true)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}