天梯赛L2-023 图着色问题(图的存储与遍历)

本题要求:
图着色问题是一个著名的NP完全问题。给定无向图 G = (V, E),问可否用K种颜色为V中的每一个顶点分配一种颜色,使得不会有两个相邻顶点具有同一种颜色?

但本题并不是要你解决这个着色问题,而是对给定的一种颜色分配,请你判断这是否是图着色问题的一个解。

输入格式:
输入在第一行给出3个整数V(0 < V <= 500)、E(>= 0)和K(0 < K <= V),分别是无向图的顶点数、边数、以及颜色数。顶点和颜色都从1到V编号。随后E行,每行给出一条边的两个端点的编号。在图的信息给出之后,给出了一个正整数N(<= 20),是待检查的颜色分配方案的个数。随后N行,每行顺次给出V个顶点的颜色(第i个数字表示第i个顶点的颜色),数字间以空格分隔。题目保证给定的无向图是合法的(即不存在自回路和重边)。

输出格式:
对每种颜色分配方案,如果是图着色问题的一个解则输出“Yes”,否则输出“No”,每句占一行。

输入样例:
6 8 3 
2 1 
1 3 
4 6 
2 5 
2 4 
5 4 
5 6 
3 6 

1 2 3 3 1 2 
4 5 6 6 4 5 
1 2 3 4 5 6 
2 3 4 2 3 4

输出样例:
Yes 
Yes 
No 
No

看完题后才发现这个不是个NP,其实这道题目就是考你个图的存储与搜索。

题目说最大点的个数为500个,然后根据题意来看是个稀疏图。(其实如果是稠密图的话很多要求都满足不了了)

所以我们选择领接表来存图,这个题目中对于每个点都有很多元素,所以我没想太多直接用了struct来存,再在struct里开个数组a【】,这个数组用来存与它连接的点,cot用来存一共有多少个点与它相连(主要是为了循环好控制条件),co是当前点涂上的颜色。

存完图后在遍历一遍图就行了。每个点都遍历一遍,看看与它相连的点有没有和它一样的颜色的。

(我开始以为暴力过不了的,结果居然五个测试点都过了,不知道是数据水还是出题人没卡我们)
 

#include <queue>
#include <cstdio>
#include <set>
#include <string>
#include <stack>
#include <cmath>
#include <climits>
#include <map>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <stdio.h>
#include <ctype.h>
#include <bitset>
#define LL long long
#define ULL unsigned long long
#define mod 1000000007
#define INF 0x7ffffff
#define mem(a,b) memset(a,b,sizeof(a))
#define MODD(a,b) (((a%b)+b)%b)
#define PI 3.1415927
//#define N 15
using namespace std;

int r[505];

struct node
{
    int co;
    int a[505];
    int cot=1;

}stu[505];

int main()
{
   int v,e,k;
   int ans = 0;
   scanf("%d%d%d",&v,&e,&k);
   for(int i=0;i<e;i++){
    int a,b;
    scanf("%d%d",&a,&b);
    stu[a].a[stu[a].cot++] = b;//这个地方括号有点多,注意一下
    stu[b].a[stu[b].cot++] = a;

   }
   int m;

   scanf("%d",&m);
   int p=1;
   for(int i=1;i<=m;i++){
       ans = 0;
    mem(r,0);//r'数组用来记用了多少种颜色的
    for(int j=1;j<=v;j++){

        scanf("%d",&stu[j].co);
        if(!r[stu[j].co]){
            r[stu[j].co]=1;
            ans++;
        }
    }
    int flag=0;
    for(int x=1;x<=v;x++){
        p=1;
       while(p<stu[x].cot){
            if((ans!=k)||stu[x].co==stu[stu[x].a[p]].co){//这个首先就判断k种颜色是不是每种都用到了

                printf("No\n");
                flag=1;
                break;
            }
            p++;
        }
        if(flag) break;
    }
    if(!flag) printf("Yes\n");
   }






return 0;

}

能力有限,写的可能有些繁琐。

猜你喜欢

转载自blog.csdn.net/qq_40620465/article/details/88766507