首页 > 试题广场 >

二分图判定

[编程题]二分图判定
  • 热度指数:1823 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定一个由n个点,m条边组成的无向图(注意,此图可能不连通),对任意1 ≤ i ≤ m存在一条边连接u[i], v[i]。回答此图是不是二分图。二分图定义为存在一种给图中每一个点染上黑白两色其中之一的着色方式,使得对每一对有边直接相连的点颜色不同。 


输入描述:
第一行输入为N和M,代表无向图的点数和边数。

接下来M行,表示M条边,每一行两个整数u[i], v[i],满足1 ≤ u[i], v[i] ≤ n,保证图中无重边,自环。

其中保证1 ≤ N, M ≤ 100000


输出描述:
一行字符串,为Yes,或者No。

Yes表示输入图是二分图。

No表示输入图不是二分图。
示例1

输入

5 7
1 2
2 3
3 4
4 1
4 5
5 2

输出

Yes

说明

如图,把1, 3, 5点染色为白,2, 4染色为黑,即可满足二分图要求,所以这个图是二分图。
示例2

输入

5 4
1 2
2 3
3 1
4 5

输出

No

说明

1, 2, 3号点无论如何染色都无法满足要求,所以不是二分图。

关于2019的校招题,我从头刷到这儿,碰到的第一个关于图的题。总结了一下图的写法,关于图的存储常用两种:邻接矩阵和邻接表;图的遍历有三种:BFS,DFS递归,DFS非递归。所以图的存储和图的遍历共有6种组合。从而我写了6种方法,经测试已全部AC,下面提供的6种AC代码可以交叉对比 从而对图的存储和图的遍历有个更清晰的认识

import java.util.*;
import static java.lang.System.in;

public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(in);
        int n = sc.nextInt(), m = sc.nextInt();
        int[][] edge = new int[m][2];
        for (int i = 0; i < m; i++) {
            edge[i][0] = sc.nextInt();
            edge[i][1] = sc.nextInt();
        }
        //arrStoreWay(edge, n);
        adjStoreWay(edge,n);
    }

    public static void arrStoreWay(int[][] data, int n) {
        int[][] graph = new int[n + 1][n + 1];
        for (int i = 0; i < data.length; i++) {
            graph[data[i][0]][data[i][1]] = 1;
            graph[data[i][1]][data[i][0]] = 1;
        }
        //arrBFS(graph,n);
        //arrDFSRecursion(graph,n);
        arrDFSStack(graph, n);
    }

    public static void adjStoreWay(int[][] data, int n) {
        HashMap<Integer, LinkedList<Integer>> graph = new HashMap<>();
        for (int i = 0; i < data.length; i++) {
            if (!graph.containsKey(data[i][0])) {
                graph.put(data[i][0], new LinkedList<>());
            }
            if (!graph.containsKey(data[i][1])) {
                graph.put(data[i][1], new LinkedList<>());
            }
            graph.get(data[i][0]).add(data[i][1]);
            graph.get(data[i][1]).add(data[i][0]);
        }
        adjBFS(graph,n);
        //adjDFSRecursion(graph,n);
        //adjDFSStack(graph,n);
    }

    public static void arrBFS(int[][] graph, int n) {
        Queue<Integer> queue = new LinkedList<>();
        HashSet<Integer> set = new HashSet<>();
        int[] marks = new int[n + 1];
        for (int i = 1; i < graph.length; i++) {
            //防止出现多个连通分量
            if (set.contains(i)) {
                continue;
            }
            queue.offer(i);
            marks[i] = 1;
            set.add(i);
            while (!queue.isEmpty()) {
                int cur = queue.poll();
                for (int j = 1; j < graph[cur].length; j++) {
                    if (graph[cur][j] == 1 && marks[cur] == marks[j]) {
                        System.out.println("No");
                        return;
                    }
                    if (graph[cur][j] == 1 && !set.contains(i)) {
                        marks[j] = -marks[cur];
                        queue.offer(j);
                        set.add(j);
                    }
                }
            }
        }
        System.out.println("Yes");
    }

    public static String res = "Yes";
    public static void arrDFSRecursion(int[][] graph, int n) {
        HashSet<Integer> set = new HashSet<>();
        int[] marks = new int[n + 1];
        for (int i = 1; i < graph.length; i++) {
            if (set.contains(i)) {
                continue;
            }
            marks[i] = 1;
            set.add(i);
            arrDFSRecursionProcess(i, graph, marks, set);
        }
        System.out.println(res);
    }

    public static void arrDFSRecursionProcess(int node, int[][] graph, int[] marks, HashSet<Integer> set) {
        for (int j = 1; j < graph[node].length; j++) {
            if (graph[node][j] == 1 && marks[node] == marks[j]) {
                res = "No";
                return;
            }
            if (graph[node][j] == 1 && !set.contains(j)) {
                marks[j] = -marks[node];
                set.add(j);
                arrDFSRecursionProcess(j, graph, marks, set);
            }
        }
    }

    public static void arrDFSStack(int[][] graph, int n) {
        HashSet<Integer> set = new HashSet<>();
        int[] marks = new int[n + 1];
        Stack<Integer> stack = new Stack<>();
        for (int i = 1; i < graph.length; i++) {
            if (set.contains(i)) {
                continue;
            }
            set.add(i);
            marks[i] = 1;
            stack.push(i);
            while (!stack.isEmpty()) {
                int cur = stack.pop();
                for (int j = 1; j < graph[cur].length; j++) {
                    if (graph[cur][j] == 1 && marks[cur] == marks[j]) {
                        System.out.println("No");
                        return;
                    }
                    if (graph[cur][j] == 1 && !set.contains(j)) {
                        stack.push(cur);
                        marks[j] = -marks[cur];
                        set.add(j);
                        stack.push(j);
                        break;
                    }
                }
            }
        }
        System.out.println("Yes");
    }

    public static void adjBFS(HashMap<Integer, LinkedList<Integer>> graph,int n) {
        Queue<Integer> queue = new LinkedList<>();
        HashSet<Integer> set = new HashSet<>();
        int[] marks = new int[n + 1];
        for (Integer item : graph.keySet()) {
            if (set.contains(item)) {
                continue;
            }
            set.add(item);
            marks[item] = 1;
            queue.offer(item);
            while (!queue.isEmpty()) {
                int cur = queue.poll();
                for (Integer iitem : graph.get(cur)) {
                    if (marks[iitem] == marks[cur]) {
                        System.out.println("No");
                        return;
                    }
                    if (!set.contains(iitem)) {
                        marks[iitem] = -marks[cur];
                        queue.offer(iitem);
                        set.add(iitem);
                    }
                }
            }
        }
        System.out.println("Yes");
    }

    public static String adjRes = "Yes";
    public static void adjDFSRecursion(HashMap<Integer, LinkedList<Integer>> graph, int n) {
        HashSet<Integer> set = new HashSet<>();
        int[] marks = new int[n + 1];
        for (Integer item : graph.keySet()) {
            if (set.contains(item)) {
                continue;
            }
            set.add(item);
            marks[item] = 1;
            adjDFSRecursionProcess(item,graph,marks,set);
        }
        System.out.println(adjRes);
    }

    public static void adjDFSRecursionProcess(int node, HashMap<Integer, LinkedList<Integer>> graph, int[] marks, HashSet<Integer> set) {
        for (Integer item : graph.get(node)) {
            if (marks[item] == marks[node]) {
                adjRes = "No";
                return;
            }
            if (!set.contains(item)) {
                set.add(item);
                marks[item] = -marks[node];
                adjDFSRecursionProcess(item,graph,marks,set);
            }
        }
    }

    public static void adjDFSStack(HashMap<Integer, LinkedList<Integer>> graph, int n) {
        HashSet<Integer> set = new HashSet<>();
        int[] marks = new int[n + 1];
        Stack<Integer> stack = new Stack<>();
        for (Integer item : graph.keySet()) {
            if (set.contains(item)) {
                continue;
            }
            set.add(item);
            marks[item] = 1;
            stack.push(item);
            while (!stack.isEmpty()) {
                int cur = stack.pop();
                for (Integer iitem : graph.get(cur)) {
                    if (marks[iitem] == marks[cur]) {
                        System.out.println("No");
                        return;
                    }
                    if (!set.contains(iitem)) {
                        set.add(iitem);
                        marks[iitem] = -marks[cur];
                        stack.push(cur);
                        stack.push(iitem);
                    }
                }
            }
        }
        System.out.println("Yes");
    }
}
编辑于 2019-08-09 12:04:49 回复(6)
 AC代码
#include <bits/stdc++.h>
 using namespace std;
 const int maxn=1e5+8;
 vector<int>G[maxn];
 int V;
 int color[maxn];
 bool dfs(int v,int c){
     color[v]=c;
     for(int i=0;i<G[v].size();i++){
         if(color[G[v][i]]==c)return false;
         if(color[G[v][i]]==0&&!dfs(G[v][i],-c))return false;
     }
     return true;
 }
 void solve(){
     for(int i=0;i<V;i++){
         if(color[i]==0)
         if(!dfs(i,1)){
             printf("No\n");
             return;
         }
     }
     printf("Yes\n");
 }
 int main()
 {
     int m;
     scanf("%d%d",&V,&m);
     for(int i=0;i<m;i++){
         int s,t;
         scanf("%d%d",&s,&t);
         G[s].push_back(t);
         G[t].push_back(s);
     }
     solve();
    return 0;
 }
注意 给出的样例 第一个样例 应该有7条边 但是 样例只给了六条!!



发表于 2019-03-05 23:45:45 回复(1)
///很简单
//定义俩个集合
///左边放一种颜色顶点
///右边放另一种颜色顶点
//当一次输入时一个集合同时出现俩个顶点就不能形成二分图
///求顶,谢谢,让大家看到

#include<iostream>
(720)#include<unordered_map>
using namespace std;
int main()
{
    int n,m;
    cin>>n>>m;
    int i=0;
    int s,t;
    unordered_map<int,int> p;
    unordered_map<int,int> q;
    while(i<m)
    {
        cin>>s>>t;
        if(((p.find(s)!=p.end())&&(p.find(t)!=p.end()))||((q.find(s)!=q.end())&&(q.find(t)!=q.end())))
        {
            cout<<"No";
            return 0;
        }
        else if(p.find(s)!=p.end())
            q.insert({t,i});
        else if(p.find(t)!=p.end())
            q.insert({s,i});
        else if(q.find(s)!=q.end())
            p.insert({t,i});
        else if(q.find(t)!=q.end())
            p.insert({s,i});
        else
        {
            p.insert({s,i});
            q.insert({t,i});
        }
        i++;
    }
    cout<<"Yes";
}

发表于 2020-02-26 11:36:37 回复(1)
#include <bits/stdc++.h>

using namespace std;

const int N = (int)1e5 + 10;

vector<int> vec[N];
int color[N];

int main(){
    int n, m;
    scanf("%d %d", &n, &m);
    for (int i = 0; i < m; i++){
        int u, v;
        scanf("%d %d", &u, &v);
        vec[u].push_back(v);
        vec[v].push_back(u);
    }
    memset(color, -1, sizeof(color));
    auto dfs = [&](auto &&self, int u, int c) {
        color[u] = c;
        for (int v : vec[u]){
            if(color[v] == color[u]){
                return false;
            } else if(color[v] == (c ^ 1)){
                continue;
            } else if(color[v] == -1){
                if(!self(self, v, c ^ 1)){
                    return false;
                }
            }
        }
        return true;
    };
    puts(dfs(dfs, 1, 0) ? "Yes" : "No");
    return 0;
}

发表于 2019-10-15 16:50:15 回复(0)
#include <bits/stdc++.h>
using namespace std;

const int N = 100007;
int n,m;
vector<int> G[N];
int a[N];

bool DFS(int u, int c){
    a[u] = c;
    for(int i=0;i<G[u].size();i++){
        int v = G[u][i];
        if(a[v]==c)
            return false;
        if(a[v]==0 && !DFS(v, -c))
            return false;
    }
    return true;
}

int main(){
    cin>>n>>m;
    for(int i=0;i<m;i++){
        int u,v;
        cin>>u>>v;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    bool flag = true;
    for(int i=0;i<n;i++){
        if(a[i]==0 && !DFS(i,1)){
            flag = false;
            break;
        }
    }
    cout<<(flag?"Yes":"No")<<endl;
    return 0;
}

发表于 2019-09-14 13:41:37 回复(0)
/*
图的m着色问题(判定或求方案),考虑DFS
以下用非递归的方法实现dfs
*/
#include<bits/stdc++.h>
using namespace std;
#define N 10000

bool ok(vector<int> edge[], int color[], int k)
{
    for(auto it : edge[k]) {
        if(color[k] == color[it]) return false;
    }
    return true;
}

bool dfs(vector<int> edge[], int n, int m, int color[])
{
    int k = 1;
    while(k >= 1) {
        color[k] += 1;
        while(color[k] <= m) { //搜索可用的颜色
            if(ok(edge, color, k)) break;
            else color[k] += 1;
        }

        if(color[k] > m) { //回溯
            color[k] = 0;
            k--;
        } else if(k >= n) { //求解完毕,输出解
            return true;  //判定是否有可行解
//            for(i = 1; i <= n; i++)  //输出着色方案
//                printf("%d ", color[i]);
//            printf("\n");
//            return; //return表示之求解其中一种解
        } else { //处理下一个顶点
            k++;
        }
    }
    return false;
}

int main()
{
//    freopen("input.txt", "r", stdin);
    int n, k, i, u, v;
    cin >> n >> k;
    vector<int> edge[n + 1];
    for(i = 0; i < k; i++) {
        cin >> u >> v;
        edge[u].push_back(v);
        edge[v].push_back(u);
    }
    int color[n + 1];
    memset(color, 0, sizeof(color));
    int m = 2; //可用m种颜色
    if(dfs(edge, n, m, color)) printf("Yes\n");
    else printf("No\n");
    return 0;
}

发表于 2019-07-13 12:11:38 回复(0)
n, m = list(map(int, input().split()))
arr = []
for i in range(m):
    arr.append(list(map(int, input().split())))
dic = dict()
for edge in arr:
    if edge[0] not in dic:
        dic[edge[0]] = [edge[1]]
    else:
        dic[edge[0]].append(edge[1])
    if edge[1] not in dic:
        dic[edge[1]] = [edge[0]]
    else:
        dic[edge[1]].append(edge[0])
def search():
    res ={}
    for key in dic:
        if key not in res:
            res[key] =1
        for point in dic[key]:
            if point not in res:
                res[point] = 1-res[key]
            else:
                if res[point] == res[key]:
                    return('No')
    return('Yes')
print(search())

编辑于 2019-02-26 08:50:25 回复(0)
#include <iostream>
#include <vector>
using namespace std;
int main(void){
    int N, M, s, e;
    bool res = true;
    cin>>N>>M;
    vector<int> grap(N, -1);
    for(int i = 0; i < M; ++i){
        cin>>s>>e;
        if(grap[s] == grap[e]){
            if(grap[s] != -1){
                res = false;
            }else{
                grap[s] = 0;
                grap[e] = 1;
            }
        }else if(grap[s] == -1){
            grap[s] = 1-grap[e];
        }else{
            grap[e] = 1-grap[s];
        }
    }
    cout<<(res ? "Yes" : "No")<<endl;
    return 0;
}
2种染色的算法很简单,判断两个端点是否都染过色,是的话如果颜色相同返回结果为false,否则给它们染上2种不同颜色,如果两个端点其中有一个没染色,将其染色为另一个端点不同的颜色。-1表示未染色,0表示染黑色,1表示染白色。
——————————更新—————————————
代码能通过但还是太年轻了,这种解题思路有错误,请忽略我的回答!
编辑于 2019-09-02 21:10:20 回复(5)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef enum { UNKNOWN = 0, BLACK = 1, WHITE = 2 } Color;

typedef struct {
  int to;
  int next;
} Edge;

void addEdge(int* head, Edge* edges, int u, int v, int i) {
  (*(edges + i)).next = *(head + u);
  (*(edges + i)).to = v;
  *(head + u) = i;
}

void printAdjList(int* head, Edge* edges, const int n) {
  int i, u;
  for (u = 1; u <= n; ++u) {
    fprintf(stdout, "vertex %d: [ ", u);
    for (i = *(head + u); i; i = (*(edges + i)).next)
      fprintf(stdout, "%d ", (*(edges + i)).to);
    fputs("]\n", stdout);
  }
  fputc(10, stdout);
}

int dfs(int* head, Edge* edges, int curr, Color color, Color* colors) {
  *(colors + curr) = color;
  int i, nei;
  for (i = *(head + curr); i; i = (*(edges + i)).next) {
    nei = (*(edges + i)).to;
    if (*(colors + nei) == color) return 0; // 我邻居的颜色与我相同,表明存在着冲突
    if (*(colors + nei) == UNKNOWN && 
        !dfs(head, edges, nei, color == BLACK ? WHITE : BLACK, colors))
      return 0;
  }
  return 1;
}

int main(const int argc, const char* argv[]) {
  int n, m, u, v;
  fscanf(stdin, "%d %d", &n, &m);
  
  int head[n + 1]; 
  Edge edges[m << 1 | 1];
  memset(head, 0x0000, sizeof head);
  
  int i = 0;
  while (m--) {
    fscanf(stdin, "%d %d", &u, &v);
    addEdge(head, edges, u, v, ++i);
    addEdge(head, edges, v, u, ++i);
  }
  
  Color colors[n + 1];
  memset(colors, UNKNOWN, sizeof colors);
  
  // 图中可能有多个连通分量 (连通分量 == 极大的连通子图)
  for (u = 1; u <= n; ++u)
    if (*(colors + u) == UNKNOWN && !dfs(head, edges, u, BLACK, colors))
      return fputs("No", stdout), 0;
  
  return fputs("Yes", stdout), 0;
}

发表于 2021-07-17 16:18:59 回复(0)
#include <iostream>
(720)#include <vector>
using namespace std;
bool dfs(vector<int> * graphs,int *colors,int i,int s){
    colors[i]=s;
    for (auto a:graphs[i]){
        if (s==colors[a]) return false;
        if (colors[a]==0 && !dfs(graphs,colors,a,-s)) return false;
    }
    return true;
}
bool paint(vector<int>* graphs,int * colors,int n){
    for (int i=1;i<=n;i++)
        if (colors[i]==0 && !dfs(graphs,colors,i,1))
            return false;
    return true;
}
int main(){
    int n,m;
    cin>>n>>m; 
    vector<int> graphs[n+1];
    for (int i=0;i<m;i++){
        int s,t;
        cin>>s>>t;
        graphs[s].push_back(t);
        graphs[t].push_back(s);
    }
    int *colors=new int[n+1];
    if (paint(graphs,colors,n))
        cout<<"Yes";
    else 
        cout<<"No";
    return 0;
}

发表于 2020-04-16 17:04:34 回复(0)
import java.util.*;
import static java.lang.System.in;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(in);
        int n = sc.nextInt();
        int m  = sc.nextInt();
        // 建图
        HashMap<Integer, HashSet<Integer>> graph =new HashMap<>();
        
        for(int i = 0; i<m; i++){
            int curr = sc.nextInt();
            int next = sc.nextInt();
            graph.putIfAbsent(curr,new HashSet());
            graph.get(curr).add(next);
        }
        //  是n+1,因为从0开始
        int[] colors = new int[n+1];
        // 我们染色三种情况,0是没有染色到,1是一种颜色,-1是一种颜色
        boolean ans = true;
        for(int cur= 1; cur<=n; cur++){
            //对于一个从来没染过色的点,初始都为1,然后我们开始爱的魔力找圈圈
            if(colors[cur] == 0  &&  !dfs(colors,1,graph, cur ))  ans =false;
        }
        //***改的,就是为了输出简单
        String res = "Yes";
        if(!ans)  res = "No";
        
        System.out.println(res);
    }
    private static boolean dfs(int[] colors, int color, HashMap<Integer, HashSet<Integer>> graph,int cur){
       //找到了一个环,然后看他现在要给的颜色和之前的颜色是不是一样的。这个根据题意好理解。
        if(colors[cur] != 0) return colors[cur] == color;
        colors[cur] = color;
        
        //非连通图的情况,到了尾巴,发现他是个一条边,这种情况肯定是对的
        if(!graph.containsKey(cur)) return true;
        
        for(int next:  graph.get(cur)){
            if(!dfs(colors, -color, graph, next)) return false;
        }
        
        return true;
    }
}

发表于 2020-04-14 05:40:58 回复(0)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5;
int n, m;
int color[maxn];
bool vis[maxn];
vector<int> G[maxn];
void add_edge(int u, int v){
 G[u].push_back(v);
 G[v].push_back(u);
}
bool dfs(int u, int col){
 vis[u] = true; color[u] = col;
 int Size = G[u].size(), v;
 for(int i = 0; i < Size; i++){
  v = G[u][i];
  if(vis[v]){
   if(color[v] == color[u]) return false;
  }
  else{
   return dfs(v, -col);
  }
 }
 return true;
}
int main(){
 scanf("%d%d", &n, &m);
 int u, v;
 for(int i = 1; i <= m; i++){
  scanf("%d%d", &u, &v);
  add_edge(u, v);
 }
 bool ok = true;
 for(int i = 1; i <= n; i++){
  if(!vis[i]){
   if(!dfs(i, 1)){
    ok = false;
    break;
   }
  }
 }
 if(ok) puts("Yes");
 else puts("No");
 return 0;
}
发表于 2020-03-28 09:32:04 回复(0)
#include <bits/stdc++.h>
using namespace std;

/*
    广度优先,给一个顶点染1,它的邻点染-1,如果发现邻点已染色且跟自己相同,则over
*/
// N<=100000 只能用邻接表法存储

struct GraphNode{
    int id;
    int color;  // 0未染色 1红 -1黑  
    vector<int> neighbors;
    GraphNode(){}
    GraphNode(int idx):id(idx),color(0){}
    GraphNode(const GraphNode &g){
        id = g.id;
        color = g.color;
    }
};

int main(){
    int N,M;
    cin>>N>>M;
    vector<GraphNode> G(N+1);
    for(int i=1;i<=N;i++){
        G[i] = GraphNode(i);
    }
    int u,v;
    for(int i=0;i<M;i++){
        cin>>u>>v;
        G[u].neighbors.push_back(v);
        G[v].neighbors.push_back(u);
    }
    queue<int> Q;
    vector<bool> visited(N+1,false);
    bool ans = true;
    for(int i=1;i<=N;i++){
        if(ans==false) break;
        if(visited[i]) continue;
        Q.push(i);
        while(!Q.empty()){
            u = Q.front();Q.pop();
            visited[u]=true;
            if(G[u].color==0)
                G[u].color = 1;
            for(auto v:G[u].neighbors){
                if(visited[v]){
                    if(G[v].color==G[u].color) {
                        ans=false;//有问题
                        break;
                    }
                    else continue;
                }
                G[v].color = -1*G[u].color;
                Q.push(v);
            }
        }
        
    }
    if(ans) cout<<"Yes"<<endl;
    else cout<<"No"<<endl;
    
    
    return 0;
}

发表于 2020-02-17 20:35:13 回复(0)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

//总结目前牛客问题 第一,没有循环输入问题, 第二 有循环输入问题, 第三 输入有多余空格问题 ,第四 中间插入多余空行问题 ....
namespace Test0001
{
    class Program
    {
       //涂色问题,相邻的边无法涂成相同颜色;
        public static void Main(string[] args)
        {
            //string line;
            //while (!string.IsNullOrEmpty(line = Console.ReadLine())) Func(line);
            Func(Console.ReadLine());
        }
        public static void Func(string line)
        {
            var s1 = line.Trim().Split(' ').Select(x => int.Parse(x)).ToArray();
            int n = s1[0], m = s1[1];//顶点和边数
            int[,] map = new int[n + 1, n + 1];
            int[] res = new int[n + 1];
            for (int i = 0; i < m; i++)
            {
                s1 = Console.ReadLine().Trim().Split(' ').Select(x => int.Parse(x)).ToArray();
                map[s1[0], s1[1]] = 1;
                map[s1[1], s1[0]] = 1;
            }
            Console.WriteLine(Fill(n, 1, map, res, -1) ? "Yes" : "No");
        }

        public static bool Fill(int n, int root, int[,] map, int[] res,int color)
        {
            res[root] = -color;
            bool flag = true;
            for (int i = 1; i <= n; i++)
            {
                if (map[root, i] == 1)//如果这两结点有边
                {
                    if (res[i] == 0) //如果与他相邻结点没有被填色
                    {
                        flag = flag && Fill(n, i, map, res, -color);
                        if (!flag) return false;
                    }
                    else if (res[i] == -color)//如果相邻结点被填充非正确颜色
                    {
                        return false;
                    }
                }
            }
            return true;
        } 
    }
}
就是填个色嘛.把结点保存至数组 黑白用 -1 和 1 代替, 循环遍历并且填充颜色,如果发现颜色冲突返回false
编辑于 2019-12-11 17:06:33 回复(0)
from collections import deque


n, m = list(map(int, input().split()))
graph = [[0] * n for _ in range(n)]
color = [0] * n

def bfs(node):
    color[node] = 1
    queue = deque([node])
    while queue:
        node = queue.popleft()
        for i in range(n):
            if graph[node][i] == 1:
                if color[i] == 0:
                    queue.append(i)
                    color[i] = -color[node]
                if color[i] == color[node]:
                    return False
    return True

for i in range(m):
    start, end = list(map(int, input().split()))
    graph[start - 1][end - 1] = 1

flag = False
for i in range(n):
    if color[i] == 0 and not bfs(i):
        flag = True
        break
if flag:
    print("No")
else:
    print("Yes")

发表于 2019-09-03 22:32:40 回复(0)
python:两个字典(哈希表),装纳两个二分图中的点。如果有两个点同时在一个字典中就输出False,其余的情况看代码,很清晰。一次就AC,自己都觉得吃惊!
import sys
def test_binary(num):
    dic1 = {}
    dic2 = {}
    for i in num:
        if (i[0] in dic1 and i[1] in dic1) or (i[0] in dic2 and i[1] in dic2):
            return False
        else:
            if i[0] in dic1:
                dic2[i[1]] = dic2.get(i[1],0)+1
            elif i[0] in dic2:
                dic1[i[1]] = dic1.get(i[1],0)+1
            elif i[1] in dic1:
                dic2[i[0]] = dic2.get(i[0],0)+1
            elif i[1] in dic2:
                dic1[i[0]] = dic1.get(i[0],0)+1
            else:
                dic1[i[0]] = dic1.get(i[0],0)+1
                dic2[i[1]] = dic2.get(i[1],0)+1
    return True
if __name__=='__main__':
    n,m = list(map(int,input().split()))
    res = []
    for line in sys.stdin.readlines():
        temp = list(map(int,line.split()))
        res.append(temp)
    if test_binary(res):
        print('Yes')
    else:
        print('No')


发表于 2019-08-16 19:25:33 回复(0)
n,m = map(int, input().split())
dic = {}
flag = 'Yes'
k = m-1 if n<m else m #避免第一个样例的情况
for i in range(k):
    u, v = map(int, input().split())
    if u not in dic:
        dic[u] = 'b'
        dic[v] = 'w'
    else:
        if v not in dic:
            if dic[u] == 'b':
                dic[v] = 'w'
            else:dic[v] = 'b'
        else:
            if dic[u] == dic[v]:
                flag = 'No'
print(flag)

发表于 2019-08-09 11:07:33 回复(1)
#include<iostream>
#include<vector>
using namespace std;
const int maxn = 1e5 + 8;
vector<int>G[maxn];
int color[maxn];
bool DFS(int v, int c) {
    color[v] = c;
    for (int i = 0; i < G[v].size(); i++) {
        if (color[G[v][i]] == c) {
            return false;
        }
        if (color[G[v][i]] == 0 && !DFS(G[v][i], -c)) {
            return false;
        }
    }
    return true;
}
int main() {
    int n, m;
    //memset(color, 0, sizeof(color));
    cin >> n >> m;
    for (int i = 0; i <= n; i++) { color[i] = 0; }
    while (m--) {
        int s, t;
        cin >> s >> t;
        //无向图
        G[s].push_back(t);
        G[t].push_back(s);
    }
    //如果是连通图,则一次dfs即可访问所有位置
    //但题目没有说明,故要依次检查各个顶点的情况
    for (int i = 1; i <= n; i++) {
        if (color[i] == 0) {
            if (!DFS(i, 1)) {
                cout << "No" << endl;
                return 0;
            }
        }
    }
    cout << "Yes" << endl;
    system("pause");
    return 0;
}

发表于 2019-07-15 15:37:08 回复(0)
java代码如下
importjava.util.Scanner;
 
publicclassMain
{
    publicstaticintn_vertex;
    publicstaticintn_edges;
    publicstaticint[][] adjMatrix;
    publicstaticint[] color;
     
    publicstaticbooleandfs(intv,intc)
    {
        color[v]=c;
        for(inti=1;i<=n_vertex;i++)
        {
            if(adjMatrix[v][i]==1)
            {
                if(color[i]==c)
                    returnfalse;
                if(color[i]==0&& !dfs(i,-c))
                    returnfalse;
            }
        }
        returntrue;
    }
     
     
    publicstaticString viewAll()
    {
        for(inti=1;i<=n_vertex;i++)
        {
            if(color[i]==0)
            {
                if(!dfs(i,1))
                {
                    return"No";
                }
            }
        }
        return"Yes";
    }
     
    publicstaticvoidmain(String[] args)
    {
        Scanner in = newScanner(System.in);
        n_vertex=in.nextInt();
        n_edges=in.nextInt();
        color=newint[n_vertex+1];
        adjMatrix=newint[n_vertex+1][n_vertex+1];
        for(inti=0;i<n_edges;i++)
        {
            intstart=in.nextInt();
            intend=in.nextInt();
            adjMatrix[start][end]=1;
            adjMatrix[end][start]=1;
        }
        System.out.println(viewAll());
    }
}

发表于 2019-03-08 19:13:53 回复(0)
# 先保存成邻接表,然后模拟染色
from collections import defaultdict
def search():
    MN=list(map(int,input().strip().split()))
    M=MN[0]
    N=MN[1]
    if M<=2:
        return "Yes"
    graph=[[] for i in range(M+1)]
    for i in range(N):
        S,E=map(int,input().strip().split())
        graph[S].append(E)
    colors=defaultdict(int)
    uncolor=set(range(1,M+1))
    to_color=[]
    for i in range(1,M+1):
        if i in uncolor:
            uncolor.remove(i)
            colors[i]=1
            to_color.append((i,1))
        while to_color:
            j,c=to_color.pop(0)
            for node in graph[j]:
                if node in uncolor:
                    uncolor.remove(node)
                    colors[node]=1-c
                    to_color.append((node,1-c))
                elif colors[node]==c:
                    return "No"
        return "Yes"
    
if __name__ == '__main__':
    print(search())

发表于 2019-03-05 22:08:15 回复(0)