poj1419Graph Coloring

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 4379   Accepted: 1985   Special Judge

Description

You are to write a program that tries to find an optimal coloring for a given graph. Colors are applied to the nodes of the graph and the only available colors are black and white. The coloring of the graph is called optimal if
a maximum of nodes is black. The coloring is restricted by the rule that no two connected nodes may be black.

Figure 1: An optimal graph with three black nodes

Input

The graph is given as a set of nodes denoted by numbers 1...n, n <= 100, and a set of undirected edges denoted by pairs of node numbers (n1, n2), n1 != n2. The input file contains m graphs. The number m is given on the first line.
The first line of each graph contains n and k, the number of nodes and the number of edges, respectively. The following k lines contain the edges given by a pair of node numbers, which are separated by a space.

Output

The output should consists of 2m lines, two lines for each graph found in the input file. The first line of should contain the maximum number of nodes that can be colored black in the graph. The second line should contain one possible
optimal coloring. It is given by the list of black nodes, separated by a blank.

Sample Input

1
6 8
1 2
1 3
2 4
2 5
3 4
3 6
4 6
5 6

Sample Output

3
1 4 5

Source

Southwestern European Regional Contest 1995

求最大独立集

独立集就是在一个图中选取一些点,这些点互不相邻,这个点集就是独立集

最大独立集就是点最多的独立集,很显然,一个图至少一个

最大独立集跟图的补图的最大团是一样的

图的补图就是把一个图原来的边都删掉,把原来互相之间没有边的点相连

最大团就是一个图的最大完全子图

完全子图就是一个图的子图是个完全图

最大完全子图就是完全子图上的点最多,很显然,一个图至少一个

求最大团就是NP完全,我学了一种爆搜

大概思路就是维护三个数组

a数组存放一个正在考虑的完全子图,b数组存放一个当前最大完全子图,

c数组存放第i个点到最后一个点这个区域内所能形成的最大团的点的数量,

很显然,c是用来剪枝的

从最后一个点依次往前选点作为第一个点丢到a中进行搜索,显然这种作法是为了维护c

由于a如果可以扩展,那么肯定是由与a中的点相邻的连点扩展(相邻就是直接与点连接),

考虑这些点,如果选出来的点跟a中所有点都相邻,那么这个点丢到a的尾巴,进行下一次搜索,

同样为了维护c,当从a中选择一个点作为前驱开始扩展时,我们枚举比这个点下标大的点里

是否有它的相邻点,如果有,就开始考虑这些点,若是当前a的数量加上c[i](i为这些点的下标),

还是无法更新当前最大团,那么就不用再考虑这个前驱了,停止关于这个前驱的扩展,

为了再快一点,每次搜索如果更新了当前最大团就停止这次搜索,换个起点我们再来,

为何这样可以保证正确性,因为毕竟我们枚举了所有起点,考虑到了所有情况,

如若不停止,反而会多出一些重复情况。

这种爆搜不太好的地方就是必须要用邻接矩阵,很浪费内存,速度的话看RP,过这个题是没问题的。

#include<map>
#include<string>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<vector>
#include<iostream>
#include<algorithm>
#include<bitset>
#include<climits>
#include<list>
#include<iomanip>
#include<stack>
#include<set>
using namespace std;
bool edge[110][110];
int n,ans,group[110],box[110],cnt[110];//box存放当前选取的点,group存放当前最大团,cnt存放第i位后可形成的最大团
bool dfs(int s,int num)
{
	for(int i=s+1;i<=n;i++)
	{
		if(cnt[i]+num<=ans)
			return 0;
		if(edge[s][i])
		{
			int j;
			for(j=0;j<num;j++)
				if(!edge[i][box[j]])
					break;
			if(j==num)
			{
				box[num]=i;
				if(dfs(i,num+1))
					return 1;
			}
		}
	}
	if(ans<num)
	{
		ans=num;
		memcpy(group,box,sizeof(int)*ans);
		return 1;
	}
	return 0;
}
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int m;
		cin>>n>>m;
		memset(edge,0,sizeof(edge));
		while(m--)
		{
			int from,to;
			cin>>from>>to;
			edge[from][to]=edge[to][from]=1;
		}
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				if(i!=j)
					edge[i][j]^=1;
		ans=1;
		for(int i=n;i>0;i--)
		{
			box[0]=i;
			dfs(i,1);
			cnt[i]=ans;
		}
		cout<<ans<<endl;
		for(int i=0;i<ans;i++)
			printf(i==0?"%d":i==ans-1?" %d\n":" %d",group[i]);
	}
}
时间: 2024-10-10 18:22:26

poj1419Graph Coloring的相关文章

CF149D. Coloring Brackets[区间DP !]

不知道为什么居中了,先把代码放这 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int N=705,MOD=1e9+7; char s[N]; long long n,f[N][N][5][5]; int st[N],top=0,m[N]; void match(){ for(int i=1;i<=

CF# 149 D Coloring Brackets(区间dp)

D - Coloring Brackets Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Practice CodeForces 149D Description Once Petya read a problem about a bracket sequence. He gave it much thought but didn't find a solut

page coloring小结

页着色是一种通过选择性物理页分配来实现把虚存映射到特定cache位置的软件方法. 最早引入页着色概念是在计算机体系结构,是为了解决地址别名问题引入的. 首先对cache是使用虚拟地址还是物理地址的问题,有很多讨论,而在使用虚拟地址时,存在一个问题叫做别名问题.所谓别名问题出现的原因就是操作系统和用户程序可能对同一个物理地址使用两种以上不同形式的虚拟地址来访问,这些地址被称作别名,他们会导致同一个数据在使用虚拟地址的cache中存在两个副本,如果其中一个数据被修改,那么另外一个就是错误的. 对于别

193 - Graph Coloring(DFS)

题目:193 - Graph Coloring 题目大意:给出一个图,图里面有点和边,要求相邻的点不可以都是黑色的,问怎样上色黑色的点最多的,给出字典序最大的那种组合情况. 解题思路:dfs每个点是黑是白,将黑的点保存记录下来,然后下次再试探某个点是黑点的时候,就看看这个点和之前的那些点有没有相邻,相邻就表示这个点不是黑点.每个试探的点只需要是这个点之后的点就可以了,因为前面的点已经试探过了. 代码: #include <stdio.h> #include <string.h> c

POJ1419 Graph Coloring(最大独立集)(最大团)

Graph Coloring Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4926   Accepted: 2289   Special Judge Description You are to write a program that tries to find an optimal coloring for a given graph. Colors are applied to the nodes of the

codeforces 149D - Coloring Brackets (区间dp)

题目大意: 给出一组合法的括号. 括号要么不涂颜色,要么就涂上红色或者绿色. 匹配的括号只能有一个有颜色. 两个相邻的括号不能有相同的颜色. 思路分析: 因为是一个合法的括号序列. 所以每个括号与之匹配的位置是一定的. 那么就可以将这个序列分成两个区间. (L - match[L] )  (match[L]+1, R) 用递归先处理小区间,再转移大区间. 因为条件的限制,所以记录区间的同时,还要记录区间端点的颜色. 然后就是一个递归的过程. #include <cstdio> #include

Codeforces Round #369 (Div. 2) C. Coloring Trees(dp)

题目链接:Codeforces Round #369 (Div. 2) C. Coloring Trees 题意: 有n个树,每个树有一个颜色,如果颜色值为0,表示没有颜色,一共有m个颜色,第j种颜色涂第i棵树需要花费pij,颜色一样且相邻的分为一组 现在要将所有颜色为0的树涂上颜色,使得这些树恰好可以分为k组,问最小的花费 题解: 考虑dp[i][j][k],表示考虑第i棵树涂第j种颜色,当前分为k组的最小花费,然后状态转移看代码,注意的是dp的初始状态 1 #include<bits/std

poj 1419Graph Coloring 【dfs+补图+计算最大团+计算最大独立集 【模板】】

题目地址:http://poj.org/problem?id=1419 Graph Coloring Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4468   Accepted: 2042   Special Judge Description You are to write a program that tries to find an optimal coloring for a given graph. Col

UVA Graph Coloring

主题如以下: Graph Coloring  You are to write a program that tries to find an optimal coloring for agiven graph. Colors are applied to the nodes of the graph and the only availablecolors are black and white. The coloring of the graph is called optimalif a