题目链接:点击进入
题目
题意
大概就是 n 点 m 边的无向图 ( 不一定联通 ) ,给你每个点的颜色,让你判断 k - 染色图 ( 就是相邻两点不能同色,所有点最多 k 种颜色的图 ) ,是输出 k ,不是输出 No
思路
k 染色图,这个 k 可以将所有点的颜色插入 set 来求,判断相邻两点是否同色有两种方法。
第一种 ( 简单 ):枚举每条边,判断两个端点是否同色;
第二种:枚举每个连通块,dfs 判断里面每条边两端是否同色。
两种方式结果相同,第一种简单点。
代码1
#include<iostream>
#include<map>
#include<set>
#include<cstring>
using namespace std;
const int maxn=1e5+10;
int n,m,k,a[maxn];
struct node
{
int x;
int y;
}p[maxn];
set<int>s;
int main( )
{
cin>>n>>m;
for(int i=1;i<=m;i++)
cin>>p[i].x>>p[i].y;
cin>>k;
while(k--)
{
s.clear();
for(int i=0;i<n;i++)
cin>>a[i],s.insert(a[i]);
int flag=0;
for(int i=1;i<=m;i++)
{
if(a[p[i].x]==a[p[i].y])
{
flag=1;
break;
}
}
if(!flag)
cout<<s.size()<<"-coloring"<<endl;
else
cout<<"No"<<endl;
}
return 0;
}
代码2
#include<iostream>
#include<map>
#include<set>
#include<cstring>
using namespace std;
const int maxn=1e5+10;
int n,m,k,head[maxn],tot,a[maxn],flag;
bool vis[maxn];
struct node
{
int to;
int next;
}edge[maxn];
set<int>s;
void init()
{
memset(head,-1,sizeof(head));
tot=0;
}
void add(int u,int v)
{
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
}
void dfs(int pos,int fa)
{
vis[pos]=1;
for(int i=head[pos];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(v==fa) continue;
if(a[v]==a[pos]) flag=1;
if(flag) return ;
if(vis[v]) continue;
dfs(v,pos);
}
}
int main( )
{
init();
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int x,y;
cin>>x>>y;
add(x,y);
add(y,x);
}
cin>>k;
while(k--)
{
s.clear();flag=0;
for(int i=0;i<n;i++) vis[i]=0;
for(int i=0;i<n;i++)
cin>>a[i],s.insert(a[i]);
for(int i=0;i<n;i++)
{
if(!vis[i]) dfs(i,-1);
if(flag) break;
}
if(!flag)
cout<<s.size()<<"-coloring"<<endl;
else
cout<<"No"<<endl;
}
return 0;
}