資料結構課程設計-檢查網路(並查集)
阿新 • • 發佈:2018-12-15
檢查網路
給定一個計算機網路以及機器間的雙向連線列表,每一條連線與允許兩端的計算機進行直接的檔案傳輸,其他計算機間若存在一條連通路徑,也可以進行間接的檔案傳輸。
要求實現功能:
任意指定兩臺計算機,判斷整個網路中是否任意兩臺機器間都可以檔案傳輸?若不可以,請給出當前網路中連通分量的個數及各個連通分量中的機器。 增加兩臺計算機之間的連線。
基本要求:
至少使用兩種結構實現。
陣列實現:
#include<iostream> #include<cstdio> #include<cstring> #define maxn 1000 using namespace std; int cc[maxn]; //用來記錄每個連通分量中的一個值,cc[1]=3:第一個連通分量中的一個值為3 int par[maxn],ran[maxn],a[maxn],b[maxn]; void Init(int n) //初始化 { for(int i=0;i<=n;++i){ par[i] = i; ran[i] = 0; } } int Find_par(int x) //尋找父節點 { if(par[x]==x) return x; return par[x] = Find_par(par[x]); } void Unite(int x,int y) //可連線的計算機了相連 { int fx = Find_par(x); int fy = Find_par(y); if(fx == fy) return ; if(ran[fx]<ran[fy]) par[fx] = fy; else{ par[fy] = fx; if(ran[fx]==ran[fy]) ran[fx]++; } } int Acount(int n) //計算連通分量個數 { int cnt=0,flag = 1,k; for(int i=1;i<=n;++i){ if(Find_par(i)==i){ cnt++; cc[cnt] = i; } } return cnt; } int main() { int n,m,ans,mac1,mac2; char op; while(n|m){ printf("請輸入計算機的數量:"); scanf("%d",&n); printf("請輸入可直接相連的計算機的對數:"); scanf("%d",&m); if(n>maxn||m>maxn){ printf("\n資料越界,請重新輸入!!!\n\n\n"); continue ; } memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); Init(n); printf("請輸入可直接相連的計算機機號:\n"); for(int i=1;i<=m;++i){ scanf("%d %d",&a[i],&b[i]); Unite(a[i],b[i]); } while(1){ printf("請輸入想要的操作(Q:查詢連通情況,A:增加連線 ,N:退出):"); cin>>op; if(op == 'Q'){ //查詢 ans = Acount(n); if(ans == 1){ printf("任意兩臺計算機均可連通\n"); } else{ printf("連通分量的個數為: %d\n",ans); for(int i=1;i<=ans;i++){ printf("第%d個連通分量中的機器有 : ",i); for(int j=1;j<=n;++j){ if(Find_par(cc[i])==Find_par(par[j])) printf("%d ",j); } printf("\n"); } printf("請輸入兩臺計算機序號,判斷其二者是都可以連通:(以0,0結束)\n"); while(scanf("%d %d",&mac1,&mac2)){ if(mac1+mac2==0) break; if(Find_par(mac1) == Find_par(mac2)) printf("%d號計算機與%d號計算機可以連通\n",mac1,mac2); else printf("二者無法連通\n"); } } } else if(op == 'A'){ //新增連線 int num; printf("請輸入新增的連線數:\n"); scanf("%d",&num); printf("請輸入新新增連線的機器號:\n"); while(num--){ scanf("%d %d",&mac1,&mac2); Unite(mac1,mac2); } continue; } else break; } printf("\n\n"); } return 0; } /* 10 9 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 輸出結果: 任意兩臺計算機均可連通 10 7 1 2 1 3 1 5 1 9 4 6 4 7 8 10 輸出結果: 連通分量的個數為: 3 第1個連通分量中的機器有 : 1 2 3 5 9 第2個連通分量中的機器有 : 4 6 7 第3個連通分量中的機器有 : 8 10 10 5 1 2 1 4 2 6 4 7 3 5 輸出結果: 連通分量的個數為: 5 第1個連通分量中的機器有 : 1 2 4 6 7 第2個連通分量中的機器有 : 3 5 第3個連通分量中的機器有 : 8 第4個連通分量中的機器有 : 9 第5個連通分量中的機器有 : 10 10 3 1 10 2 8 8 10 輸出結果: 連通分量的個數為: 7 第1個連通分量中的機器有 : 1 2 8 10 第2個連通分量中的機器有 : 3 第3個連通分量中的機器有 : 4 第4個連通分量中的機器有 : 5 第5個連通分量中的機器有 : 6 第6個連通分量中的機器有 : 7 第7個連通分量中的機器有 : 9 10 6 1 2 1 3 3 8 8 10 4 5 6 7 輸出結果: 連通分量的個數為: 4 第1個連通分量中的機器有 : 1 2 3 8 10 第2個連通分量中的機器有 : 4 5 第3個連通分量中的機器有 : 6 7 第4個連通分量中的機器有 : 9 */
結構體實現:
#include <iostream> #include <cstdio> #define maxn 1000 using namespace std; int cc[maxn]; //連通分量 struct node { int data; int ran; int parent; }t[maxn]; void Init(int n) { for(int i=1;i<=n;++i) { t[i].data = i; t[i].ran = 0; t[i].parent = i; } } int Find_par(int x) { if(t[x].parent==x) return x; return t[x].parent = Find_par(t[x].parent); } void Unite(int x,int y ) { x=Find_par(x); y=Find_par(y); if(x==y) return ; if( t[x].ran < t[y].ran ) t[x].parent=y; else{ t[y].parent=x; if( t[x].ran==t[y].ran) t[x].ran++; } } int Acount(int n) { int cnt=0,flag = 1,k; for(int i=1;i<=n;++i){ if(t[i].parent == i){ cnt++; cc[cnt] = i; } } return cnt; } int main() { int n,m,ans,mac1,mac2; char op; while(n|m){ printf("請輸入計算機的數量:"); scanf("%d",&n); printf("請輸入可直接相連的計算機的對數:"); scanf("%d",&m); if(n>maxn||m>maxn){ printf("\n資料越界,請重新輸入!!!\n\n\n"); continue ; } Init(n); printf("請輸入可直接相連的計算機機號:\n"); for(int i=1;i<=m;++i){ scanf("%d %d",&mac1,&mac2); Unite(mac1,mac2); } while(1){ printf("請輸入想要的操作(Q:查詢連通情況,A:增加連線 ,N:退出):"); cin>>op; if(op == 'Q'){ //查詢 ans = Acount(n); if(ans == 1){ printf("任意兩臺計算機均可連通\n"); } else{ printf("連通分量的個數為: %d\n",ans); for(int i=1;i<=ans;i++){ printf("第%d個連通分量中的機器有 : ",i); for(int j=1;j<=n;++j){ if(Find_par(cc[i])==Find_par(t[j].parent)) printf("%d ",j); } printf("\n"); } printf("請輸入兩臺計算機序號,判斷其二者是都可以連通:(以0,0結束)\n"); while(scanf("%d %d",&mac1,&mac2)){ if(mac1+mac2==0) break; if(Find_par(mac1) == Find_par(mac2)) printf("%d號計算機與%d號計算機可以連通\n",mac1,mac2); else printf("二者無法連通\n"); } } } else if(op == 'A'){ //新增連線 int num; printf("請輸入新增的連線數:\n"); scanf("%d",&num); printf("請輸入新新增連線的機器號:\n"); while(num--){ scanf("%d %d",&mac1,&mac2); Unite(mac1,mac2); } continue; } else break; } printf("\n\n"); } return 0; }