C/C++之二分图问题

本文探讨了如何在不形成重边和子环的前提下,利用最多两种颜色对具有n个不同顶点的图进行染色,确保相邻顶点颜色不同。通过深度优先搜索(DFS)算法实现图的二分验证,采用数组而非容器简化节点信息存储,提高代码效率。

给定一个具有n个不同顶点的图,要给图上每个顶点染色,并且要使相邻的顶点颜色不同,问是否最多用2种颜色进行染色?没有重边和子环

#include<iostream>
#include<vector>
using namespace std;
class node{
	public:
		int color;
		int arr[100];
		int count;
		node()
		{
			color=0;
			count=0;
		}
		add(int num)
		{
			arr[count++]=num;
		}
}n[4];
bool dfs(int no,int color)
{
	n[no].color=color;
	for(int i=0;i<n[no].count;i++)
	{
		if(n[n[no].arr[i]].color==color)
			return false;
		else if(n[n[no].arr[i]].color==0)
		{
			bool result=dfs(n[no].arr[i],-color);
			if(!result)
				return false;
		}
	}
	return true;
}
int main()
{
	n[0].add(1);
	n[0].add(3);
	n[1].add(0);
	n[1].add(2);
	n[2].add(1);
	n[2].add(3);
	n[3].add(0);
	n[3].add(2);
	cout<<dfs(0,1);
	return 0;
}

这个好难,主要是要保存其他节点的信息,刚开始使用容器,但是发现容器太麻烦,而且因为来回调用也没啥提示,随意搞得很难受,想来想去还是数组比较简单些,当然也可以自定义容器,不过意义不大。

人工智能关于最大二分图的程序代码: #include #include 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=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 #include #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、付费专栏及课程。

余额充值