usingnamespacestd;typedefstructufs_elem_st{structufs_elem_st*next,*prev;structufs_elem_st*parent;}ufs_elem_st,*ufs_elem_t;typedefstructufs_st{ufs_elem_st*roots;}ufs_st,*ufs_t;typedefstructstar_st{ufs_elem_stufs_e" />

欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Timus 1392

系統(tǒng) 1673 0
      
        #include 
      
      
        <
      
      
        iostream
      
      
        >
      
      
        
using namespace std;

typedef
struct ufs_elem_st {
struct ufs_elem_st * next, * prev;
struct ufs_elem_st * parent;
} ufs_elem_st,
* ufs_elem_t;

typedef
struct ufs_st {
ufs_elem_st
* roots;
} ufs_st,
* ufs_t;

typedef
struct star_st {
ufs_elem_st ufs_elem;
int x,y,z,r;
} star_st,
* star_t;

int K;
short star_idx[ 1001 ] = { 0 };
star_st stars[
1001 ] = { 0 };

ufs_elem_t ufs_get_root(ufs_elem_t me) {
ufs_elem_t my_root
= me;
while ( my_root -> parent != my_root && my_root -> parent != NULL )
my_root
= my_root -> parent;

me
-> parent = my_root; // 路徑壓縮
return my_root;
}

void ufs_add_root(ufs_t ufs, ufs_elem_t me) {
ufs_elem_t my_root
= ufs_get_root(me);
if ( NULL != ufs -> roots ) {
my_root
-> next = ufs -> roots;
ufs
-> roots -> prev = my_root;
}
ufs
-> roots = my_root;
my_root
-> prev = NULL;
}

void ufs_join(ufs_t ufs, ufs_elem_t friend_elem, ufs_elem_t me) {
ufs_elem_t my_root
= ufs_get_root(me);
ufs_elem_t friend_root
= ufs_get_root(friend_elem);
ufs_elem_t final_root
= NULL;

if ( NULL != my_root -> next )
my_root
-> next -> prev = my_root -> prev;
if ( NULL != my_root -> prev )
my_root
-> prev -> next = my_root -> next;
if ( ufs -> roots == my_root )
ufs
-> roots = my_root -> next;
my_root
-> next = my_root -> prev = NULL;

if ( NULL != friend_root -> next )
friend_root
-> next -> prev = friend_root -> prev;
if ( NULL != friend_root -> prev )
friend_root
-> prev -> next = friend_root -> next;
if ( ufs -> roots == friend_root )
ufs
-> roots = friend_root -> next;
friend_root
-> next = friend_root -> prev = NULL;

// 合并集合
star_t s1 = (star_t)my_root, s2 = (star_t)friend_root;
// 根據(jù)star的編號決定誰作為集合的代表,這方便最后根據(jù)集合中最小的索引號來排序集合
if ( s1 - stars < s2 - stars ) {
friend_root
-> parent = my_root;
final_root
= my_root;
}
else {
my_root
-> parent = friend_root;
final_root
= friend_root;
}

if ( NULL != ufs -> roots ) {
final_root
-> next = ufs -> roots;
ufs
-> roots -> prev = final_root;
}
ufs
-> roots = final_root;
}

bool check(star_t s1, star_t s2) {
int distSquare = (s1 -> x - s2 -> x) * (s1 -> x - s2 -> x) + (s1 -> y - s2 -> y) * (s1 -> y - s2 -> y) + (s1 -> z - s2 -> z) * (s1 -> z - s2 -> z);
int r1r2Square = (s1 -> r + s2 -> r) * (s1 -> r + s2 -> r);
if ( distSquare < r1r2Square )
return true ;
else
return false ;
}

int set_id_cmp( const void * i1, const void * i2) {
ufs_elem_t e1
= (ufs_elem_t)(stars + * ( short * )i1);
ufs_elem_t e2
= (ufs_elem_t)(stars + * ( short * )i2);
return ufs_get_root(e1) - ufs_get_root(e2);
}

int set_elem_id_cmp( const void * i1, const void * i2) {
return * ( short * )i1 - * ( short * )i2;
}

void print_set_elem( int start, int len) {
int i;
len
-- ;
for (i = 0 ;i < len;i ++ )
cout
<< star_idx[start + i] << " , " ;
cout
<< star_idx[start + i] << endl;
}

int main() {
int i,j,k;
bool find_grp;
ufs_st ufs
= { 0 };
cin
>> K;
for ( i = 0 ;i < K;i ++ )
cin
>> stars[i].x >> stars[i].y >> stars[i].z >> stars[i].r;

for ( i = 0 ;i < K;i ++ ) {
for ( j = i + 1 ;j < K;j ++ ) {
if ( ufs_get_root((ufs_elem_t)(stars + i)) == ufs_get_root((ufs_elem_t)(stars + j)) ) // 都一個集合了,不處理
continue ;
// 相連, 把對方假如到我的集合中,誰當(dāng)集合代表取決于對方的集合代表的編號和我的集合代表的編號
if ( check(stars + i, stars + j) == true )
ufs_join(
& ufs, (ufs_elem_t)(stars + i), (ufs_elem_t)(stars + j));
}
}

for ( i = 0 ;i < K;i ++ )
star_idx[i]
= i;

// 根據(jù)集合代表的編號大小來排序集合元素,確保了屬于同一個集合的元素都在連續(xù)空間
// 集合之間按集合代表的編號排序
qsort(star_idx, K, sizeof ( short ), set_id_cmp);

for ( i = 0 ,j = 1 ,k = 0 ;i < K - 1 ;i ++ ) {
// i 與 i+1 屬于同一個集合
if ( ufs_get_root((ufs_elem_t)(stars + star_idx[i])) == ufs_get_root((ufs_elem_t)(stars + star_idx[i + 1 ])) ) {
j
++ ;
}
else { // 不屬于同一個集合
// 對一個集合的元素排序,根據(jù)元素之間的編號
qsort(star_idx + k, j, sizeof ( short ), set_elem_id_cmp);
print_set_elem(k, j);
j
= 1 ; // 新一個集合的元素個數(shù)初始化
k = i + 1 ; // 新一個集合的第一個元素的位置
}
}
qsort(star_idx
+ k, j, sizeof ( short ), set_elem_id_cmp);
print_set_elem(k, j);

return 0 ;
}

剛開始以為是圖論的求強連通子圖,后來發(fā)現(xiàn)也沒必要,就是不斷地把符合條件的元素加在一起形成集合,剛好是并查集的經(jīng)典應(yīng)用。

不過題目在輸出順序要求上帶了些難度,所以在并查集的合并過程中做了些改動。

這代碼除了并查集,另一個有趣的地方是怎樣把算法數(shù)據(jù)結(jié)構(gòu)和邏輯數(shù)據(jù)結(jié)構(gòu)結(jié)合起來應(yīng)用,模仿LINUX內(nèi)核的數(shù)據(jù)結(jié)構(gòu)。

Timus 1392


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 日韩大尺度电影在线观看 | 亚洲综合在线播放 | 欧美成人18 | 日本精品不卡 | 一区二区三区免费 | 国产97免费视频 | 欧美不卡视频一区发布 | 国产在线视频一区二区 | 国产激情 | 五月丁香综合啪啪成人小说 | 午夜在线亚洲男人午在线 | 国产欧美日韩在线不卡第一页 | 五月天中文在线 | 日本久久中文字幕 | 奇米第四色在线观看 | 狠狠色狠狠色综合久久第一次 | 日韩中文字幕免费在线观看 | 久久综合九色综合97欧美 | 精品AV一区二区三区久久 | 国产精品亚洲天堂 | 好吊妞gao988在线播放 | 精品一区二区高清在线观看 | 欧美日本免费一区二区三区 | 日韩福利在线 | 美女用震蛋叫爽的视频95视频 | 欧美一区二区三区精品国产 | 亚洲最大成人在线 | 婷五月综合| 富二代视频污 | 色网站综合| 91精品国产91久久综合 | 欧美日一区二区 | 久久精品 | 色婷婷导航 | 伦一区二区三区中文字幕v亚洲 | 欧美日韩一区二区中文字幕 | 91视频在 | v视界成人影院在线视频 | 182tv在线观看国产路线一 | 国产精品亚洲综合 | 久久综合九色综合欧美狠狠 |