地图着色

求解可以有多少种不同的解法(回溯法、递归)

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>

int count=0;
typedef struct ArcNode//边表结点
{
    int adjvex;//邻接点域,存储该顶点对应的下标
    struct ArcNode *nextarc; //链域,指向下一个邻接点
} ArcNode;
typedef struct VNode//顶点表结点
{
	int color;
    int data;//顶点域,存储顶点信息
    ArcNode *firstarc;//边表头指针
} VNode;
typedef struct Graph
{
    VNode adjList[10];
    int numNodes, numEdges; // 图中当前顶点数和边数
} Graph;
 
//图的建立与初始化
Graph *CreateALGraph(Graph *G)
{
	int i, j, k;
	ArcNode *pe;
    G=(Graph *)malloc(sizeof(Graph));   
	printf("顶点数与边数:\n");
    scanf("%d %d",&(G->numNodes),&(G->numEdges));
    for (i= 0 ; i < G->numNodes; i++)
    {
        G->adjList[i].firstarc = NULL;//将边表置为空表
    }
    for (k = 0; k <  G->numEdges; k++)//建立边表
    {
        scanf("%d %d",&i,&j);

        pe = (ArcNode*)malloc(sizeof(ArcNode));
        pe->adjvex = j;//邻接序号为j 将pe的指针指向当前顶点上指向的结点
        pe->nextarc =G->adjList[i].firstarc;
        G->adjList[i].firstarc = pe;//将当前顶点的指针指向pe
 
  
        pe = (ArcNode*)malloc(sizeof(ArcNode));
        pe->adjvex = i;
        pe->nextarc =G->adjList[j].firstarc;
        G->adjList[j].firstarc = pe;
        
    }
    return G;
}

int check(Graph *G,int step)
{
	ArcNode *p=G->adjList[step].firstarc;
	while(p!=NULL)
	{
		if(G->adjList[p->adjvex].color==G->adjList[step].color)
			return 0;
		p=p->nextarc;
	}
	return 1;
}

void f(Graph *G,int step)
{
	int i;
	if(step==G->numNodes)
	{
		printf("\n一组:\n");
		for(i=0;i<G->numNodes;i++)
			printf("%3d",G->adjList[i].color);
		count++;
	}
	else
	{
		for(i=1;i<=4;i++)
		{
			G->adjList[step].color=i;
			if(check(G,step))
				f(G,step+1);
			G->adjList[step].color=0;
		}
	}
}

int main()
{
	Graph *G=(Graph*)malloc(sizeof(Graph));
	G=CreateALGraph(G);
	f(G,0);
	printf("\nsum=%d\n",count);
	system("pause");
	return 0;
}

使用的数据:

5 8
1 2
1 3
1 4
2 3
2 4
2 5
3 4
4 5 //答案是48 //每个序号都减去1

5 7
0 1
0 2
1 2
1 3
2 3
2 4
3 4//答案是96
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值