二分图算法c++详解

二分图(Bipartite Graph)是一种特殊的图,它的顶点可以被分成两个互不相交的集合,使得图中的每条边都是连接两个不同集合中的顶点。判断一个图是否是二分图,可以使用深度优先搜索(DFS)或广度优先搜索(BFS)算法。

下面是一个使用DFS实现的判断二分图的C++代码示例:

#include <iostream>
#include <vector>
#include <climits>

using namespace std;

const int MAX_V = 1000;
vector<int> adjList[MAX_V]; // 邻接列表表示图
int color[MAX_V]; // 用于标记顶点的颜色,0表示未着色,1和2表示两个不同的颜色
bool visited[MAX_V]; // 标记顶点是否被访问过

bool isBipartite(int v, int c = 1) {
    if (color[v] != 0) {
        return color[v] == c;
    }

    color[v] = c;
    visited[v] = true;

    for (int u : adjList[v]) {
        if (!visited[u]) {
            if (!isBipartite(u, 3 - c)) {
                return false;
            }
        } else if (color[u] == c) {
            return false;
        }
    }
    return true;
}

int main() {
    int V, E, u, v;

    // 输入图的信息
    cin >> V >> E;
    for (int i = 0; i < E; i++) {
        cin >> u >> v;
        adjList[u].push_back(v);
        adjList[v].push_back(u);
    }

    // 初始化颜色和访问标记
    for (int i = 1; i <= V; i++) {
        color[i] = 0;
        visited[i] = false;
    }

    // 对每个连通分量进行判断
    bool bipartite = true;
    for (int i = 1; i <= V; i++) {
        if (!visited[i]) {
            if (!isBipartite(i)) {
                bipartite = false;
                break;
            }
        }
    }

    if (bipartite) {
        cout << "The graph is bipartite." << endl;
    } else {
        cout << "The graph is NOT bipartite." << endl;
    }

    return 0;
}

在这个代码示例中:

  1. adjList 是一个邻接列表,用于存储图的信息。
  2. isBipartite 函数实现了DFS算法,用于判断一个图是否是二分图。
  3. color 用于标记顶点的颜色,初始值为 0,表示未着色。在DFS过程中,如果顶点的颜色为 0,则将其着色为当前颜色 c。如果顶点的颜色不为 0,则检查其颜色是否和当前颜色 c 相同,如果相同则返回 false,表示图不是二分图。
  4. visited 用于标记顶点是否被访问过,防止重复访问同一个顶点。
  5. 英文完全是耍帅~~~

在主函数中,首先读入图的信息,然后对每个连通分量调用 isBipartite 函数进行判断,最后输出判断结果。

请注意,这个代码示例假设图的顶点编号从 1 开始。如果你的图顶点编号从 0 开始,需要对相关部分进行相应的修改。

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
人工智能关于最大二分图的程序代码: #include<stdio.h> #include<string.h> main() { bool map[100][300]; int i,i1,i2,num,num1,que[300],cou,stu,match1[100],match2[300],pque,p1,now,prev[300],n; scanf("%d",&n); for(i=0;i<n;i++) { scanf("%d%d",&cou;,&stu;); memset(map,0,sizeof(map)); for(i1=0;i1<cou;i1++) { scanf("%d",&num;); for(i2=0;i2<num;i2++) { scanf("%d",&num1;); map[i1][num1-1]=true; } } num=0; memset(match1,int(-1),sizeof(match1)); memset(match2,int(-1),sizeof(match2)); for(i1=0;i1<cou;i1++) { p1=0; pque=0; for(i2=0;i2<stu;i2++) { if(map[i1][i2]) { prev[i2]=-1; que[pque++]=i2; } else prev[i2]=-2; } while(p1<pque) { now=que[p1]; if(match2[now]==-1) break; p1++; for(i2=0;i2<stu;i2++) { if(prev[i2]==-2&&map;[match2[now]][i2]) { prev[i2]=now; que[pque++]=i2; } } } if(p1==pque) continue; while(prev[now]>=0) { match1[match2[prev[now]]]=now; match2[now]=match2[prev[now]]; now=prev[now]; } match2[now]=i1; match1[i1]=now; num++; } if(num==cou) printf("YES\n"); else printf("NO\n"); } } dfs实现过程: #include<stdio.h> #include<string.h> #define MAX 100 bool map[MAX][MAX],searched[MAX]; int prev[MAX],m,n; bool dfs(int data) { int i,temp; for(i=0;i<m;i++) { if(map[data][i]&&!searched[i]) { searched[i]=true; temp=prev[i]; prev[i]=data; if(temp==-1||dfs(temp)) return true; prev[i]=temp; } } return false; } main() { int num,i,k,temp1,temp2,job; while(scanf("%d",&n)!=EOF&&n!=0) { scanf("%d%d",&m,&k); memset(map,0,sizeof(map)); memset(prev,int(-1),sizeof(prev)); memset(searched,0,sizeof(searched)); for(i=0;i<k;i++) { scanf("%d%d%d",&job;,&temp1;,&temp2;); if(temp1!=0&&temp2;!=0) map[temp1][temp2]=true; } num=0; for(i=0;i<n;i++) { memset(searched,0,sizeof(searched)); dfs(i); } for(i=0;i<m;i++) { if(prev[i]!=-1) num++; } printf("%d\n",num); } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值