目的:判断是不是vertex cover。
输入:
N <=10000 总点数 0~N-1
M <=10000 总边数
M条边
K <=100 查询数
K个查询:
格式:
Nv v[1] v[2]...v[Nv]
Nv 集合的顶点数 v[i] 顶点的参数
输出:
如果是Vertex cover 输出 Yes
如果不是 输出No。
算法:
判断是不是vertex cover ,一个集合,图的每一条边至少包括集合的一个点。则称为vertex。暴力枚举。用链表存边。每次查询,看是否存在点,若不存在,输出No.遍历完全后输出Yes。
#include<stdio.h>
#include<vector>
#include<map>
using namespace std;
const int maxn = 10010;
vector<int> g[maxn];
int N,M,K;
map<int,bool> h;
int Nv;
bool isvertexcover()
{
for(int i=0;i<N;i++)
{
for(int j=0;j<g[i].size();j++)
{
int u = i;
int v = g[i][j];
if(h[u]==false&&h[v]==false)
{
return false;
}
}
}
return true;
}
int main()
{
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);
}
scanf("%d",&K);
for(int i=0;i<K;i++)
{
scanf("%d",&Nv);
h.clear();
for(int j=0;j<Nv;j++)
{
int v;
scanf("%d",&v);
h[v] = true;
}
if(isvertexcover())
{
printf("Yes\n");
}else
{
printf("No\n");
}
}
return 0;
}
反思:可以从点出发,看是否每条边都包括了。也可以从边出发,看边的两端点是否存在在集合中。