Sicily 1090 highway + Kruskal +并查集实现

来源:互联网 发布:中国经济数据对比 编辑:程序博客网 时间:2024/06/11 01:39

Sicily 1090 highway

 

1.       并查集。

适用于集合论中,用来判断给出的两点A、B是否在同一个集合中,若不在一个集合中,则将他们合并。具体方法是维护2个一维数组:

Step1:初始化一维数组root[]使每个index存放自身,(即自己的root为自己,N个元素组成N个集合)

Index

1

2

3

4

5

6

7

8

root[index]

1

2

3

4

5

6

7

8

for(int i=1;i<=n;i++){root[i]=i;}

step2: 连接操作(克鲁斯卡尔中表现为 依次添加边)

 

Index

1

2

3

4

5

6

7

8

root[index]

1

1

1

4

1

6

7

6

 

Step3: 

 maintain an array to record the rank of eachset, initiate every single element. This array is intented to judge whetherSetA should be combined to SetB or SetB should be combined to SetA,mainlyaccording to the rank of the root.

for(int i=1;i<=n;i++){rankk[i]=0;}

Step4:


Index

1

2

3

4

5

6

7

8

root[index]

1

1

1

4

1

1

7

1

这时(6,8)集合被合并到(1,2,3,5)组合中,形成(1,2,3,5,6,8)(4)(7)组合。更新root[6] root[8], 这里有一点,为什么不是更新root[1] root[2] root[3] root[5]的值为6呢。这里依据的是step3中的rank数组值来判定。

 

Step5 依次类推,直到N个顶点的无向图形成N-1条边为止。

 

附:并查集core code:

int root(int a){if( a==vertex[a])return a;else        return vertex[a]=root(vertex[a]);//update and maintain vertex[]; extraordinarily vital to update all nodes to a single root.}

return vertex[a]=root(vertex[a]); //不采用return root(vertex[a]); 
将结构扁平化。集合中每个元素的root值统一为一个。

void merge(int a,int b){int roota=root(a);int rootb=root(b);if (rankk[roota]>rankk[rootb]){vertex[rootb]=roota;}else if (rankk[roota]<rankk[rootb]){vertex[roota]=rootb;}else{vertex[roota]=rootb;rankk[rootb]++;}}

sicily 1090 highway的克鲁斯卡尔版本实现:

#include <iostream>#include <algorithm>using namespace std;struct road{int a,b,distanc;};int vertex[501];int rankk[501];road ro[250000];int arr[501][501];bool cmp(const road &a,const road &b)  //add const & modifier{return a.distanc<b.distanc;}int root(int a){if( a==vertex[a])return a;else        return vertex[a]=root(vertex[a]);//update and maintain vertex[]; extraordinarily vital to update all nodes to a single root.}void merge(int a,int b){int roota=root(a);int rootb=root(b);if (rankk[roota]>rankk[rootb]){vertex[rootb]=roota;}else if (rankk[roota]<rankk[rootb]){vertex[roota]=rootb;}else{vertex[roota]=rootb;rankk[rootb]++;}}int main(){int testcase;cin>>testcase;while (testcase--){int n,temp;cin>>n;int aa=0;for (int i=1;i<=n;i++){for(int j=1;j<=n;j++){cin>>temp;arr[i][j]=temp;ro[aa].a=i;ro[aa].b=j;ro[aa].distanc=temp;aa++;}}sort(ro,ro+aa,cmp);int maxroad=0;for(int i=1;i<=n;i++){vertex[i]=i;rankk[i]=0;}for(int i=0;i<aa;i++) {int begi=ro[i].a;int end=ro[i].b;int weig=ro[i].distanc;if(root(begi)!=root(end)){merge(begi,end);maxroad=weig;}}cout<<maxroad<<endl;if (testcase!=0){cout<<endl;}}return 0;}


0 0
原创粉丝点击