图的二着色问题

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 20:57   1780   0

问题描述:对于给定的图G,如果存在一种用两种颜色对顶点着色的方案,使得图中任意一条边所连接的两个顶点着不同颜色,则称图G是可二着色的。

实验任务:对于给定的图G,计算G是否可二着色

数据输入:第1行有2个正整数m, n,表示给定图G有n个顶点和m条边,顶点编号1,2,...,n。接下来m行中,每行有两个正整数u,v,表示图G的一条边(u,v)

结果输出:可二着色输出"Yes",否则输出"No"

直观想法,深搜或者广搜,一个顶点涂一个颜色,下一个顶点涂相反颜色。如果搜索到涂过的顶点,判断与当前顶点颜色是否相同,是则表明无法二着色,立即退出。直至全部搜索完成。

事实上,图如果无法二着色,那么必然有环,且环的顶点数必然为奇数,但是这个有什么算法呢,emmm,没想到,直接用最简单直观的深搜吧

#include <bits/stdc++.h>
using namespace std;

typedef struct{
 int vexnum; //顶点数 
 int arcnum; //边数 
 int **arc; //邻接矩阵
}Matrix_Graph;

Matrix_Graph CreateNewGraph(int n, int m)
{
 int i, j;
 Matrix_Graph graph;
 
 graph.vexnum = n;
 graph.arcnum = m;
 graph.arc = new int*[n+1];
 for(i = 1; i <= n; ++i){
  graph.arc[i] = new int[n+1];
  for(j = 1; j <= n; ++j)
   graph.arc[i][j] = 0;   
 }
 while( m-- ){
  cin >> i >> j;
  graph.arc[i][j] = graph.arc[j][i] = 1;
 }
 return graph;
}

void dfs(const Matrix_Graph& graph, int vex, bool visited[], bool color[], bool nowColor, bool& res)
{
 visited[vex] = true; // 标记访问 
 color[vex] = nowColor; // 涂色 
 cout << "vex " << vex << ": ";
 if( color[vex] ){
  cout << "red\n";
 }else{
  cout << "black\n";
 } 
 
 for(int i = 1; i <= graph.vexnum; ++i)
 {
  // 首先判断两点是否连通 
  if( graph.arc[vex][i] == 1 )
  {
   // 若访问过,且颜色一致,说明失败 
   if( visited[i] && color[i]==nowColor ){
    res = false;
    return; 
   }else if( !visited[i] ){
    // !nowColor表示下一个顶点涂另一种颜色 
    dfs(graph, i, visited, color, !nowColor, res);
    if( !res )
     return; 
   }   
  }
 }  
}

void Dfs_Graph(const Matrix_Graph& graph, bool& res)
{
 bool visited[graph.vexnum+1] = {false};
 bool color[graph.vexnum+1] = {false};
 bool nowColor = false;
 for(int i = 1; res && i<=graph.vexnum; ++i)
  if( !visited[i] )
   dfs(graph, i, visited, color, nowColor, res); 
}

bool Cover_2color(const Matrix_Graph& graph)
{
 bool res = true;
 Dfs_Graph(graph, res);
 return res;  
}

int main()
{
 int n, m;
 cin >> n >> m;
 
 Matrix_Graph graph = CreateNewGraph(n, m);
 
 if( Cover_2color(graph) ){
  cout << "Yes\n";
 }else{
  cout << "No\n";
 }
 
 return 0;
}
//Test1 
//12 10
//1 3
//1 6
//2 8
//3 7
//4 5
//5 6
//5 8
//2 9
//9 10
//11 12

//Test2
//12 10
//1 3
//1 6
//2 8
//3 7
//4 5
//5 6
//5 8
//2 9
//9 10
//8 9

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP