原帖 http://luojilie.blog.163.com/blog/static/191826963201176111715304/
Description
已知集合A={a1,a2,……an},及集合上的关系R={ (ai,aj) | ai,aj?A, i?j},其中(ai,aj)表示ai与aj间存在冲突关系。要求将A划分成互不相交的子集A1,A2,……Ak,(k?n),使任何子集中的元素均无冲突关系,同时要求分子集个数尽可能少
Sample Input
A={1,2,3,4,5,6,7,8,9}
R={ (2,8), (9,4), (2,9), (2,1), (2,5), (6,2), (5,9),(5,6), (5,4), (7,5), (7,6), (3,7), (6,3) }
Sample Output
A1={ 1,3,4,8 }
A2={ 2,7 }
A3={ 5 }
A4={ 6,9 }
(可行的子集划分)
Hint
算法思想:
利用循环筛选。从第一个元素开始,凡与第一个元素无冲突的元素划归一组;再将剩下的元素重新找出互不冲突的划归第二组;直到所有元素进组
所用数据结构
冲突关系矩阵
r[i][j]=1, i,j有冲突
r[i][j]=0, i,j无冲突
循环队列cq[n]
数组result[n]存放每个元素分组号
工作数组newr[n]
工作过程:
初始状态:A中元素放于cq中,result和newr数组清零,组号group=1
第一个元素出队,将r矩阵中第一行“1”拷入newr中对应位置,这样,凡与第一个元素有冲突的元素在newr中对应位置处均为“1”,下一个元素出队
若其在newr中对应位置为“1”,有冲突,重新插入cq队尾,参加下一次分组
若其在newr中对应位置为“0”, 无冲突,可划归本组;再将r矩阵中该元素对应行中的“1”拷入newr中
如此反复,直到9个元素依次出队,由newr中为“0”的单元对应的元素构成第1组,将组号group值“1”写入result对应单元中
令group=2,newr清零,对cq中元素重复上述操作,直到cq中front==rear,即队空,运算结束
//Author: essence_of_ACMER
//Time:2011.8.6
//Theme:Array_Subset
#include <iostream>
using namespace std;
#define N 9
int front=0,rear=0,group=0;
void division(int r[][N],int n,int cq[ ],int newer[ ],int result[ ]) //主要函数
{
int k,pre,i;
for(k=0;k<n;k++)
{cq[k]=k+1;newer[k]=0;}
front=n-1;
rear=n-1;
group=1;
pre=0;
do{front=(front+1)%n;
i=cq[front];
if(i<pre) //分组
{
group++;
result[i-1]=group;
for(k=0;k<n;k++) newer[k]=r[i-1][k];
}
else if(newer[i-1]!=0) //用冲突就放到下一组
{
rear=(rear+1)%n;
cq[rear]=i;
}
else //无冲突就放入该组
{
result[i-1]=group;
for(k=0;k<n;k++)
newer[k]+=r[i-1][k];
}
pre=i; //pre用来判断一轮是否搞完
}while(front!=rear);
}
int main()
{ //system("pause");
int a[N]={0},r[N][N]={0,1,0,0,0,0,0,0,0,
1,0,0,0,1,1,0,1,1,
0,0,0,0,0,1,1,0,0,
0,0,0,0,1,0,0,0,1,
0,1,0,1,0,1,1,0,1,
0,1,1,0,1,0,1,0,0,
0,0,1,0,1,1,0,0,0,
0,1,0,0,0,0,0,0,0,
0,1,0,1,1,0,0,0,0};
int newer[N]={0},result[N]={0};
division(r,N,a,newer,result); //函数调用
//system("pause");
for(int k=0;k<N;k++)
a[k]=k+1;
//system("pause");
for(k=1;k<=group;k++) //输出各组数据
{
cout<<"Group "<<k<<":"<<endl;//system("pause");
for(int j=0;j<N;j++)
{ if(result[j]==k) cout<<a[j]<<" ";}
cout<<endl;
}
return (0);
}