zoukankan      html  css  js  c++  java
  • 九度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 }

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

  • 相关阅读:
    iOS商品详情、ffmpeg播放器、指示器集锦、自定义圆弧菜单、实用工具等源码
    android愤怒小鸟游戏、自定义View、掌上餐厅App、OpenGL自定义气泡、抖音电影滤镜效果等源码
    iOS渐变视图&动画库、腰杆、音频水滴水波手势、多种对话框、四级展开效果等源码
    android应用市场、社区客户端、漫画App、TensorFlow Demo、歌词显示、动画效果等源码
    iOS炫酷动画图案、多种选择器、网络测速、滑动卡片效果等源码
    android多框架实现短视频应用、3D手势旋转、banner控件、指南针、智能管家等应用源码
    iOS 仿看了吗应用、指南针测网速等常用工具、自定义弹出视图框架、图片裁剪、内容扩展等源码
    android完整资讯App、Kotlin新闻应用MVP + RxJava + Retrofit + Dagger2、优雅区间选择器等源码
    iOS运营级B2B服务平台App、自定义图标库、个人中心页面、识别身份证Demo、瀑布流等源码
    Flutter中的浮动按钮 FloatingActionButton
  • 原文地址:https://www.cnblogs.com/jasonJie/p/5777642.html
Copyright © 2011-2022 走看看