• 九度oj 题目1109:连通图


    题目描述:

        给定一个无向图和其中的所有边,判断这个图是否所有顶点都是连通的。

    输入:

        每组数据的第一行是两个整数 n 和 m(0<=n<=1000)。n 表示图的顶点数目,m 表示图中边的数目。如果 n 为 0 表示输入结束。随后有 m 行数据,每行有两个值 x 和 y(0<x, y <=n),表示顶点 x 和 y 相连,顶点的编号从 1 开始计算。输入不保证这些边是否重复。

    输出:

        对于每组输入数据,如果所有顶点都是连通的,输出"YES",否则输出"NO"。

    样例输入:
    4 3
    1 2
    2 3
    3 2
    3 2
    1 2
    2 3
    0 0
    
    样例输出:
    NO
    YES

    这个题一开始用深度优先搜索做的,代码如下
     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cstring>
     4 
     5 int map[1002][1002];
     6 int flag[1002];
     7 int n, m;
     8 
     9 void dfs(int k) {
    10     flag[k] = 1;
    11     for(int i = 1; i <= n; i++) {
    12         if(flag[i] == 0 && map[k][i] == 1) {
    13             dfs(i);
    14         }
    15     } 
    16 }
    17 
    18 int main(int argc, char const *argv[])
    19 {
    20     //freopen("input.txt","r",stdin);
    21     while(scanf("%d %d",&n,&m) != EOF && n != 0) {
    22         memset(map,0, sizeof(map));
    23         memset(flag, 0, sizeof(flag));
    24 
    25         while(m--) {
    26             int a, b;
    27             scanf("%d %d",&a, &b);
    28             map[a][b] = map[b][a] = 1;
    29         }
    30         flag[1] = 1;
    31         dfs(1);
    32         bool isOk = true;
    33         for(int i = 1; i <=n; i++) {
    34             if(flag[i] == 0) {
    35                 isOk = false;
    36                 break;
    37             }
    38         }
    39         if(isOk) {
    40             puts("YES");
    41         }
    42         else {
    43             puts("NO");
    44         }
    45 
    46     }    
    47     return 0;
    48 }

    但耗时略长,内存占用略大

    后来试了试迪杰特斯拉算法的变形

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cstring>
     4 
     5 int map[1002][1002];
     6 int flag[1002];
     7 int n, m;
     8 
     9 void dfs(int k) {
    10     flag[k] = 1;
    11     for(int i = 1; i <= n; i++) {
    12         if(flag[i] == 0 && map[k][i] == 1) {
    13             dfs(i);
    14         }
    15     } 
    16 }
    17 
    18 int main(int argc, char const *argv[])
    19 {
    20     freopen("input.txt","r",stdin);
    21     while(scanf("%d %d",&n,&m) != EOF && n != 0) {
    22         memset(map,0, sizeof(map));
    23         memset(flag, 0, sizeof(flag));
    24 
    25         while(m--) {
    26             int a, b;
    27             scanf("%d %d",&a, &b);
    28             map[a][b] = map[b][a] = 1;
    29         }
    30         flag[1] = 1;
    31         
    32         for(int i = 2; i <= n; i++) {
    33             for(int j = 1; j <= n; j++) {
    34                 if(flag[j] == 0 && map[1][j] == 1) {
    35                     flag[j] = 1;
    36                     for(int k = 1; k <= n; k++) {
    37                         if(map[j][k] == 1) {
    38                             map[1][k] = 1;
    39                         }
    40                     }
    41                 }
    42             }
    43         }
    44 
    45         bool isOk = true;
    46         for(int i = 1; i <=n; i++) {
    47             if(flag[i] == 0) {
    48                 isOk = false;
    49                 break;
    50             }
    51         }
    52         if(isOk) {
    53             puts("YES");
    54         }
    55         else {
    56             puts("NO");
    57         }
    58 
    59     }    
    60     return 0;
    61 }

    但耗时更长

    也试了试flyod算法

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cstring>
     4 
     5 int map[1002][1002];
     6 int n, m;
     7 
     8 int main(int argc, char const *argv[])
     9 {
    10     //freopen("input.txt","r",stdin);
    11     while(scanf("%d %d",&n,&m) != EOF && n != 0) {
    12         memset(map,0, sizeof(map));
    13 
    14         while(m--) {
    15             int a, b;
    16             scanf("%d %d",&a, &b);
    17             map[a][b] = map[b][a] = 1;
    18         }
    19         map[1][1] = 1;
    20         for(int i = 1; i <= n; i++) {
    21             for(int j = 1; j <= n; j++) {
    22                 for(int k = 1; k <= n; k++) {
    23                     if(map[j][i] == 1 && map[i][k] == 1) {
    24                         map[j][k] = 1;
    25                     }
    26                 }
    27             }
    28         }
    29 
    30 
    31         bool isOk = true;
    32         for(int i = 1; i <=n; i++) {
    33             if(map[1][i] == 0) {
    34                 isOk = false;
    35                 break;
    36             }
    37         }
    38         if(isOk) {
    39             puts("YES");
    40         }
    41         else {
    42             puts("NO");
    43         }
    44 
    45     }    
    46     return 0;
    47 }

    直接超时了

    突然会想起一个月前做的题,好像叫做并查集的东西,代码如下

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cstring>
     4 
     5 int next[1002];
     6 int n, m;
     7 
     8 int find(int t) {
     9     while(next[t] != 0) {
    10         t = next[t];
    11     }
    12     return t;
    13 }
    14 
    15 int main(int argc, char const *argv[])
    16 {
    17     //freopen("input.txt","r",stdin);
    18     while(scanf("%d %d",&n,&m) != EOF && n != 0) {
    19         memset(next, 0, sizeof(next));
    20 
    21         while(m--) {
    22             int a, b;
    23             scanf("%d %d",&a, &b);
    24             int fa = find(a);
    25             int fb = find(b);
    26             if(fa != fb) {
    27                 next[fa] = b; 
    28             }
    29         }
    30         
    31         int isOk = 0;
    32         for(int i = 1; i <= n; i++) {
    33             if(next[i] == 0) {
    34                 isOk++;
    35                 if(isOk >= 2) {
    36                     puts("NO");
    37                     break;
    38                 }
    39             }
    40         }
    41         if(isOk == 1) {
    42             puts("YES");
    43         }
    44 
    45     }    
    46     return 0;
    47 }

    耗时和内存都有质的飞跃,但如何再进一步优化呢?

  • 相关阅读:
    【leetcode_easy_greedy】1403. Minimum Subsequence in Non-Increasing Order
    【leetcode_easy_sort】1030. Matrix Cells in Distance Order
    word2010 标题编号
    WORD2013中如何使用多级列表自动编号(转)
    Javaweb权限管理设计思路 (转)
    前后端分离模式下的权限设计方案 (转)
    Axure rp8.1.0.3381 3382 激活码(2019-07-26 亲测可用) 转
    通达OA开发网址
    C# Winform 跨线程更新UI控件常用方法汇总 (转)
    C#中的Invoke
  • 原文地址:https://www.cnblogs.com/jasonJie/p/5777642.html
Copyright © 2020-2023  润新知