图着色问题
题目详情 - 7-1 图着色问题 (25 分) (pintia.cn)
给一个(V,E)的无向图,k种颜色,给每个点都染色,看看染的色能不能让相邻的两个点不是同一种颜色,可以输出yes,不可以输出no
其实在做题目要快准狠,看一段长文字,就知道考的哪个点,提炼出要点才是主要的,而不是其他的一些花里胡哨的东西
本题:①必须要用满k种颜色②不是树,只是图,也就是图不一定连通,可以用dfs其实
但这个题数据范围挺小,可以直接暴力
dfs:
#include<iostream> #include<cstring> using namespace std; int n,m,k; const int N=1000; int mp[N][N],st[N],s[N],a[N],f; void dfs(int u) { for(int i=1;i<=n;i++) { if(mp[u][i]) { if(a[u]==a[i]) { f=0; return ; } if(!st[i]) { st[i]=1; dfs(i); } } } } int main(){ cin>>n>>m>>k; while(m--) { int a,b; cin>>a>>b; mp[a][b]=1; mp[b][a]=1; } int q; cin>>q; while(q--) { memset(st,0,sizeof(st)); memset(s,0,sizeof(s)); int t=0; for(int i=1;i<=n;i++) { cin>>a[i]; if(!s[a[i]]) { t++; s[a[i]]=1; } } if(t!=k) { cout<<"No"<<endl; continue; } f=1; for(int i=1;i<=n;i++) { if(!f) break; if(!st[i]) { st[i]=1; dfs(i); } } if(f) cout<<"Yes"<<endl; else cout<<"No"<<endl; } }
这个用了邻接表来存储以及搜索
下面用链式向前星来记录(不是自己写的,自己写的错了QAQ问了某位大佬要的代码)
#include <iostream> #include<cstring> using namespace std; const int N =1e6; int e[N],ne[N],h[N],idx,clo[N]; bool st[N],flag,st1[N]; void add(int a,int b) { e[idx]=b; ne[idx]=h[a]; h[a]=idx++; } void dfs(int u) { if(flag)return ; if(st[u])return; st[u]=1; for(int i=h[u];i!=-1;i=ne[i]) { if(clo[u]==clo[e[i]]) { flag=1; return ; } if(!st[e[i]]) dfs(e[i]); } return ; } int main() { memset(h,-1,sizeof h); int n,m,k; cin>>n>>m>>k; if(n==1) { cout<<"Yes"<<endl; return 0; } while(m--) { int a,b; cin>>a>>b; add(a,b); add(b,a); } int y; cin>>y; while(y--) { if(n==1) { cout<<"Yes"<<endl; continue; } memset(st,0,sizeof st); memset(st1,0,sizeof st1); flag=0; for(int i=1;i<=n;i++) { cin>>clo[i]; st1[clo[i]]=1; } int s=0; for(int i=1;i<=1000;i++)if(st1[i])s++; if(s!=k) { cout<<"No"<<endl; continue; } for(int i=1;i<=n;i++) { if(!st[i]) dfs(i); } if(flag) cout<<"No"<<endl; else cout<<"Yes"<<endl; } return 0; }
还可以直接暴力,也是问了某位大佬QAQ,但自己又写一遍23分,还有2分不知道
#include<iostream> #include<vector> #include<set> using namespace std; const int N=550; vector<int> v[N]; int a[N]; set<int>q; int n,m,k; int main(){ cin>>n>>m>>k; while(m--) { int a,b; cin>>a>>b; v[a].push_back(b); v[b].push_back(a); } int p; cin>>p; while(p--) { q.clear(); for(int i=1;i<=n;i++) { cin>>a[i]; q.insert(a[i]); } if(q.size()!=k) { cout<<"No"<<endl; continue; } int f=1; for(int i=1;i<=n;i++) { for(int j=1;j<=v[i].size();i++) { if(a[i]==a[v[i][j]]) f=0; } } if(f) cout<<"Yes"<<endl; else cout<<"No"<<endl; } return 0; }
********************************
我要笑死了,最后一种方法怎么做成这样,两层循环那里错了,现在重新修改一下,25分耶!
#include<iostream> #include<set> #include<vector> using namespace std; const int N=1e5+10; set<int> s; vector<int> v[N]; int a[N]; int main(){ int n,m,k; cin>>n>>m>>k; while(m--) { int a,b; cin>>a>>b; v[a].push_back(b); v[b].push_back(a); } int q; cin>>q; while(q--) { s.clear(); for(int i=1;i<=n;i++) { cin>>a[i];//每个点着上什么颜色 s.insert(a[i]); } if(s.size()!=k) { cout<<"No"<<endl; continue; } int f=1; for(int i=1;i<=n;i++) { for(int j=0;j<v[i].size();j++) { if(a[i]==a[v[i][j]]) { f=0; } } } if(f) cout<<"Yes"<<endl; else cout<<"No"<<endl; } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具