經過一天的奮鬥,解決~~~ ^_^
description
已知集合a=,及集合上的關係r=,其中(ai,aj)表示ai與aj間存在衝突關係。要求將a劃分成互不相交的子集a1,a2,……ak,(k?n),使任何子集中的元素均無衝突關係,同時要求分子集個數盡可能少
sample input
a=r=
sample output
a1=
a2=a3=
a4=(可行的子集劃分)
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,即隊空,運算結束
code:
//author: essence_of_acmer
//theme:array_subset
#include
<
iostream
>
using
namespace
std;
#define
n 9int
front=0
,rear=0
,group=0
;void
division(
intr[n],
intn,
intcq[ ],
intnewer[ ],
intresult[ ])
//主要函式
front=n
-1;rear=n
-1;group=1
;pre=0
;doelse
if(newer[i-1
]!=0)
//用衝突就放到下一組
else
//無衝突就放入該組
pre=
i;
//pre用來判斷一輪是否搞完
}while
(front
!=rear);
}int
main()
,r[n][n]=;
intnewer[n]
=,result[n]=;
division(r,n,a,newer,result);
//函式呼叫
//system("pause");
for(
intk=0
;k<
n;k++
)a[k]=k
+1;//
system("pause");
for(k=1
;k<=
group;k
++)
//輸出各組資料
cout
<<
endl;
}return(0
);}
佇列應用 劃分子集問題
集合a如下 a 集合r中 a,b 表示a與b是衝突關係,不能放在同一子集中 r 求一可行的子集劃分,使a劃分為互不相交的子集,並使子集個數盡量少。include using namespace std define maxsize 10 迴圈佇列元素個數應加一 define error 0 defi...
資料結構 鏈式佇列的實現與應用舉例 報數問題
鏈式佇列是一種常見的佇列實現方式,通過鍊錶儲存佇列的各個資料元素,並設定兩個指標,分別指向隊頭和隊尾。應用佇列可以解決報數問題。報數問題 設有n個人站成一排,從左向右的編號分別為1 n,現在從左向右報數 1,2,1,2,1,2 數到 1 的人出列,數到 2 的人站到隊伍最右邊。報數過程反覆進行,直到...
資料結構 迴圈佇列的實現與應用舉例 報數問題
迴圈佇列是一種常見的佇列實現方式,各個資料元素依次儲存,並設定兩個指標,分別指向隊頭和隊尾,在插入和刪除資料時,隊頭指標和隊尾指標會迴圈使用儲存空間。應用佇列可以解決報數問題。報數問題 設有n個人站成一排,從左向右的編號分別為1 n,現在從左向右報數 1,2,1,2,1,2 數到 1 的人出列,數到...