05-树8 File Transfer

  课上例题。

  这题考查对并查集的运用以及对之前并查算法的优化。

  1 #include <stdio.h>
  2 
  3 #define MAXN 10000                    /* 集合最大元素个数 */
  4 
  5 typedef int ElementType;            
  6 typedef ElementType SetName;        /* 默认用根节点的下标作为结点名称 */
  7 typedef ElementType SetType[MAXN];    /* 假设集合元素下标从 0 开始 */
  8 
  9 void Initialization(SetType S, int N);
 10 SetName Find(SetType S, ElementType X);
 11 void Union(SetType S, SetName Root1, SetName Root2);
 12 void Input_connection(SetType S);
 13 void Check_connection(SetType S);
 14 void Check_netWork(SetType S, int N);
 15 
 16 int main()
 17 {
 18     SetType S;
 19     int N;
 20     char in;
 21     scanf("%d\n", &N);
 22     Initialization( S, N );
 23     
 24     do {
 25         scanf("%c", &in);
 26         switch ( in ) {
 27             case 'I':    Input_connection( S );    break;
 28             case 'C':    Check_connection( S );    break;
 29             case 'S':    Check_netWork( S, N );    break;
 30         }
 31     } while ( in != 'S' );
 32     
 33     return 0;
 34 }
 35 
 36 void Input_connection(SetType S)
 37 {
 38     ElementType x1, x2;
 39     SetName Root1, Root2;
 40     
 41     scanf("%d %d\n", &x1, &x2);
 42     Root1 = Find(S, x1-1);
 43     Root2 = Find(S, x2-1);
 44     
 45      if ( Root1 != Root2 )
 46          Union(S, Root1, Root2);
 47 }
 48 
 49 void Check_connection(SetType S)
 50 {    /* 检查 是否 连通 */
 51     ElementType x1, x2;
 52     SetName Root1, Root2;
 53     
 54     scanf("%d %d\n", &x1, &x2);
 55     Root1 = Find(S, x1-1);
 56     Root2 = Find(S, x2-1);
 57     
 58     if ( Root1 == Root2 ) printf("yes\n");
 59     else                   printf("no\n");
 60     
 61 }
 62 
 63 void Check_netWork(SetType S, int N)
 64 {    /* 检查 连通性 */
 65     int i, cnt = 0;
 66     
 67     for ( i = 0; i < N; i++ ) {
 68         if ( S[i] < 0 )        cnt++; 
 69     }    
 70     
 71     if ( cnt == 1 )
 72         printf("The network is connected.\n");
 73     else 
 74         printf("There are %d components.\n", cnt);
 75 }
 76 
 77 void Union(SetType S, SetName Root1, SetName Root2)
 78 {
 79     /* 保证 小集合 并入 大集合 */
 80     if ( S[Root1] < S[Root2] ) { /* 如果 Root1 规模大 */
 81         S[Root1] += S[Root2];
 82         S[Root2] = Root1;         /* Root2 并入 Root1 */ 
 83     }
 84     else {                         /* 如果 Root2 规模大 */
 85         S[Root2] += S[Root1];
 86         S[Root1] = Root2;         /* Root1 并入 Root2 */ 
 87     }
 88 }
 89 
 90 SetName Find(SetType S, ElementType X)
 91 {
 92     if ( S[X] < 0 )  /* 找到集合的根 */ 
 93         return X;
 94     else
 95         return S[X] = Find(S, S[X]); /* 路径压缩 */ 
 96 }
 97 
 98 void Initialization(SetType S, int N)
 99 {    /* 集合元素全部初始化为 -1 */ 
100     int i;
101     for ( i = 0; i < N; i++ ) 
102         S[i] = -1;
103 }

  不得不说,这里的 switch 语句用的太漂亮了,赞。

转载于:https://www.cnblogs.com/wgxi/p/9997830.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值