图的m着色问题 (回溯 求路径)

输入:

请输入点的个数和色数(p m):5 4
请输入边的个数: 8
输入边的连接信息(点1 点2):
1 3
1 2
1 4
2 3
2 4
2 5
3 4
4 5

输出:

方法 1 : 1 2 3 4 1
方法 2 : 1 2 3 4 3
方法 3 : 1 2 4 3 1
方法 4 : 1 2 4 3 4
方法 5 : 1 3 2 4 1
方法 6 : 1 3 2 4 2
方法 7 : 1 3 4 2 1
方法 8 : 1 3 4 2 4
方法 9 : 1 4 2 3 1
方法 10 : 1 4 2 3 2
方法 11 : 1 4 3 2 1
方法 12 : 1 4 3 2 3
方法 13 : 2 1 3 4 2
方法 14 : 2 1 3 4 3
方法 15 : 2 1 4 3 2
方法 16 : 2 1 4 3 4
方法 17 : 2 3 1 4 1
方法 18 : 2 3 1 4 2
方法 19 : 2 3 4 1 2
方法 20 : 2 3 4 1 4
方法 21 : 2 4 1 3 1
方法 22 : 2 4 1 3 2
方法 23 : 2 4 3 1 2
方法 24 : 2 4 3 1 3
方法 25 : 3 1 2 4 2
方法 26 : 3 1 2 4 3
方法 27 : 3 1 4 2 3
方法 28 : 3 1 4 2 4
方法 29 : 3 2 1 4 1
方法 30 : 3 2 1 4 3
方法 31 : 3 2 4 1 3
方法 32 : 3 2 4 1 4
方法 33 : 3 4 1 2 1
方法 34 : 3 4 1 2 3
方法 35 : 3 4 2 1 2
方法 36 : 3 4 2 1 3
方法 37 : 4 1 2 3 2
方法 38 : 4 1 2 3 4
方法 39 : 4 1 3 2 3
方法 40 : 4 1 3 2 4
方法 41 : 4 2 1 3 1
方法 42 : 4 2 1 3 4
方法 43 : 4 2 3 1 3
方法 44 : 4 2 3 1 4
方法 45 : 4 3 1 2 1
方法 46 : 4 3 1 2 4
方法 47 : 4 3 2 1 2
方法 48 : 4 3 2 1 4
 

#include <iostream>
#include <algorithm>
using namespace std;
#define N 100

int p;    //顶点数 
int ed;   //边数
int m;    //颜色数 
int g[N][N];  //0,1表示顶点相连情况
int sum;
int x[N]; //每个点的着色情况

//判断当前着色是否合法 
bool isOk(int i)   //i:当前在着色的顶点  
{
	for(int j=1;j<=i;j++)  //j:枚举目前为止所有已经着过色的顶点
	{
		if(g[j][i]==1&&x[j]==x[i]) return false;
	} 
	return true;
}

void BackTrack(int i)  //把探索顶点当作深搜 第i层/第i个顶点
{
	if(i>p)
	{
		sum++;
		cout<<"方法"<<sum<<": ";
		for(int j=1;j<=p;j++) cout<<x[j]<<" ";
		cout<<endl;
	}
	else
	{
		for(int j=1;j<=m;j++)  //i是顶点 j是探索每层可选的颜色 
		{
			x[i] = j;
            if(isOk(i)) 
			{
				BackTrack(i + 1);
				x[i] = 0;  //回溯时恢复现场把颜色清除 (可以省略 
			}
            x[i] = 0;
		}
	}
} 

int main()
{
	cout<<"请输入点的个数和色数(p m):";
	cin>>p>>m;
	cout<<"请输入边的个数: ";
	cin>>ed;
	cout<<"输入边的连接信息(点1 点2):"<<endl;
	int p1,p2;
	for(int i=1;i<=ed;i++)
	{
		cin>>p1>>p2;
		g[p1][p2]=g[p2][p1]=1;
	}
	BackTrack(1);
    return 0;
}   

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值