标签:print 题意 插入 describe black each 个数 邻接 i++
A vertex cover of a graph is a set of vertices such that each edge of the graph is incident to at least one vertex of the set. Now given a graph with several vertex sets, you are supposed to tell if each of them is a vertex cover or not.
Each input file contains one test case. For each case, the first line gives two positive integers N and M (both no more than 1), being the total numbers of vertices and the edges, respectively. Then M lines follow, each describes an edge by giving the indices (from 0 to N?1) of the two ends of the edge.
After the graph, a positive integer K (≤ 100) is given, which is the number of queries. Then K lines of queries follow, each in the format:
Nv v[1] v[2] v[3] v[Nv]
where N?v?? is the number of vertices in the set, and [‘s are the indices of the vertices.
For each query, print in a line Yes
if the set is a vertex cover, or No
if not.
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
No
Yes
Yes
No
No
题意:给定一个图的若干结点和边,输入k个点集,要求判读每次的点集是否连接了图中所有的边
思路:vector存入每个点的临界点(邻接矩阵会超内存),对于每次给定的点集,记点集中点的个数为x,遍历这x个点的邻接点,在set集合中加入由x和这个邻接点组成的边,set可以去重。最后统计set中边的个数和图中边的个数的关系输出Yes或者No
注意:因为边包含连接这条边的两个顶点的信息,因此需要自定义结构体表示边,并且需要重写<操作符,因为set要求元素可以进行<运算 。这里比较坑的地方是1 9和9 1表示同样的边,但<操作符重载的时候很难实现这种去重,因此在把边加入set中的时候,总是让边的第一个顶点表示编号小的,再插入set中。< 操作符的重载需要遵循严格弱序化
严格弱序化:对于操作数a,b
a<b 表示a<b
b<a 表示b<a
!(a<b)&&!(b<a) 表示a==b
在set使用<操作符的时候,会先比较a<b,再比较b<a。因此在重载的时候,需要保证不相等的两个操作数两次比较返回不同的结果。而对于相同的操作数,需要保证两次比较都返回false。
代码如下:(注释部分为邻接矩阵法,测试点2 3内存超限)
#include<cstdio> #include<vector> #include<set> using namespace std; vector<int> v[10005]; struct node{ int a,b; bool operator <(const node& nod)const{ if(a!=nod.a) return a<nod.a; else return b<nod.b; } }; int main(){ int n,m; int a,b; scanf("%d%d",&n,&m); for(int i=0;i<m;i++){ scanf("%d%d",&a,&b); v[a].push_back(b); v[b].push_back(a); } int k,num; scanf("%d",&k); set<node> s; for(int i=0;i<k;i++){ s.clear(); scanf("%d",&num); int temp; for(int j=0;j<num;j++){ scanf("%d",&temp); for(vector<int>::iterator it=v[temp].begin();it!=v[temp].end();it++){ node tempNode; tempNode.a=temp; tempNode.b=*it; if(tempNode.a>tempNode.b){ int temp=tempNode.a; tempNode.a=tempNode.b; tempNode.b=temp; } s.insert(tempNode); } } if(s.size()==m){ printf("Yes\n"); } else printf("No\n"); } return 0; } //#include<cstdio> //#include<vector> //#include<algorithm> //using namespace std; //bool counted[10005][10005]={false}; //vector<int> v; //struct node{ // int a,b; //}; //vector<node> ass; //int n,m; //bool G[10005][10005]={false}; //void isCover(vector<int> &v){ // int sum=0; // for(vector<int>::iterator it=v.begin();it!=v.end();it++){ // int ver=*it; // for(int i=0;i<n;i++){ // if(G[ver][i]!=0&&counted[ver][i]==false){ // sum++; // counted[ver][i]=counted[i][ver]=true; // node temp; // temp.a=ver; // temp.b=i; // ass.push_back(temp); // } // } // } // if(sum==m) // printf("Yes\n"); // else // printf("No\n"); // for(vector<node>::iterator it=ass.begin();it!=ass.end();it++){ // node temp=*it; // counted[temp.a][temp.b]=counted[temp.b][temp.a]=false; // } //} //int main(){ // int a,b; // scanf("%d%d",&n,&m); // for(int i=0;i<m;i++){ // scanf("%d%d",&a,&b); // G[a][b]=G[b][a]=1; // } // int k=0; // int num; // scanf("%d",&k); // for(int i=0;i<k;i++){ // v.clear(); // scanf("%d",&num); // int temp; // for(int j=0;j<num;j++){ // scanf("%d",&temp); // v.push_back(temp); // } // isCover(v); // } // return 0; //}
标签:print 题意 插入 describe black each 个数 邻接 i++
原文地址:https://www.cnblogs.com/foodie-nils/p/13280482.html