zoukankan      html  css  js  c++  java
  • hihocoder 1322

    题目链接:http://hihocoder.com/problemset/problem/1322

    时间限制:10000ms
    单点时限:1000ms
    内存限制:256MB

    描述

    给定一个包含 N 个顶点 M 条边的无向图 G ,判断 G 是不是一棵树。

    输入

    第一个是一个整数 T ,代表测试数据的组数。 (1 ≤ T ≤ 10)

    每组测试数据第一行包含两个整数 N 和 M 。(2 ≤ N ≤ 500, 1 ≤ M ≤ 100000)

    以下 M 行每行包含两个整数 a 和 b ,表示顶点 a 和顶点 b 之间有一条边。(1 ≤ ab ≤ N)

    输出

    对于每组数据,输出YES或者NO表示 G 是否是一棵树。

    样例输入
    2
    3 2
    3 1
    3 2
    5 5
    3 1
    3 2
    4 5
    1 2
    4 1 
    样例输出
    YES
    NO

    首先,如何判断一个图是不是一棵树。

    第一个想到的当然是n-1条边;

    那么光n-1条边就够了吗,显然还有一个条件,就是这个图是连通图。

    它给的样例中,边不重复出现,那么判断m是否等于n-1其实非常方便;

    所以我们只要想办法得到一个图是不是连通图即可。

    从某种角度上来讲,可以说是一道裸的并查集模板题,那可以说就是一道水题了。

     1 #include<cstdio>
     2 using namespace std;
     3 struct Edge{
     4     int u,v;
     5 };
     6 int n,m;
     7 int par[505],ran[505];
     8 void init()
     9 {
    10     for(int i=1;i<=n;i++) par[i]=i,ran[i]=0;
    11 }
    12 int find(int x)
    13 {
    14     if(par[x] == x) return x;
    15     else return( par[x] = find(par[x]) );
    16 }
    17 void unite(int x,int y)
    18 {
    19     x=find(x),y=find(y);
    20     if(x == y) return;
    21     if(ran[x] < ran[y]) par[x]=y;
    22     else
    23     {
    24         par[y]=x;
    25         if(ran[x] == ran[y]) ran[x]++;
    26     }
    27 }
    28 bool isSame(int x,int y){return( find(x) == find(y) );}
    29 int main()
    30 {
    31     int t;
    32     scanf("%d",&t);
    33     while(t--)
    34     {
    35         scanf("%d%d",&n,&m);
    36         init();
    37         for(int i=1;i<=m;i++)
    38         {
    39             int from,to;
    40             scanf("%d%d",&from,&to);
    41             if(!isSame(from,to)) unite(from,to);
    42         }
    43         bool flag=1;
    44         int pa=find(1);
    45         for(int i=2;i<=n;i++)
    46         {
    47             if(pa!=find(i)){
    48                 flag=0;
    49                 break;
    50             }
    51         }
    52         if(flag && m==n-1) printf("YES
    ");
    53         else printf("NO
    ");
    54     }
    55 }

    当然,如果不用并查集,用搜索的话,又可以是一道非常裸的DFS题?……embarrassing……

     1 #include<cstdio>
     2 #include<vector>
     3 using namespace std;
     4 struct Edge{
     5     int u,v;
     6 };
     7 vector<Edge> adj[505]; 
     8 int n,m;
     9 bool vis[505];
    10 void dfs(int now)
    11 {
    12     vis[now]=1;
    13     for(int i=0;i<adj[now].size();i++)
    14     {
    15         Edge edge=adj[now][i];
    16         int next=edge.v;
    17         if(!vis[next]) dfs(next);
    18     }
    19 }
    20 int main()
    21 {
    22     int t;
    23     scanf("%d",&t);
    24     while(t--)
    25     {
    26         scanf("%d%d",&n,&m);
    27         for(int i=1;i<=n;i++)
    28         {
    29             adj[i].clear();
    30             vis[i]=0;
    31         }
    32         for(int i=1;i<=m;i++)
    33         {
    34             int from,to;
    35             scanf("%d%d",&from,&to);
    36             adj[from].push_back((Edge){from,to});
    37             adj[to].push_back((Edge){to,from});
    38         }
    39         dfs(1);
    40         bool flag=1;
    41         for(int i=1;i<=n;i++)
    42         {
    43             if(!vis[i]){
    44                 flag=0;
    45                 break;
    46             }
    47         }
    48         if(flag && m==n-1) printf("YES
    ");
    49         else printf("NO
    ");
    50     }
    51 }

    然后又随手码了一个BFS模板……在新加坡就是这么刷水题的……感觉对不起自己现在熬的夜……难受……

     1 #include<cstdio>
     2 #include<vector>
     3 #include<queue>
     4 using namespace std;
     5 struct Edge{
     6     int u,v;
     7 };
     8 vector<Edge> adj[505];
     9 int n,m;
    10 bool vis[505];
    11 void bfs()
    12 {
    13     queue<int> q;
    14     q.push(1);
    15     vis[1]=1;
    16     while(!q.empty())
    17     {
    18         int now=q.front();q.pop();
    19         for(int i=0;i<adj[now].size();i++)
    20         {
    21             Edge edge=adj[now][i];
    22             int next=edge.v;
    23             if(!vis[next]){
    24                 vis[next]=1;
    25                 q.push(next);
    26             }
    27         }
    28     }
    29 }
    30 int main()
    31 {
    32     int t;
    33     scanf("%d",&t);
    34     while(t--)
    35     {
    36         scanf("%d%d",&n,&m);
    37         for(int i=1;i<=n;i++)
    38         {
    39             adj[i].clear();
    40             vis[i]=0;
    41         }
    42         for(int i=1;i<=m;i++)
    43         {
    44             int from,to;
    45             scanf("%d%d",&from,&to);
    46             adj[from].push_back((Edge){from,to});
    47             adj[to].push_back((Edge){to,from});
    48         }
    49         bfs();
    50         bool flag=1;
    51         for(int i=1;i<=n;i++)
    52         {
    53             if(!vis[i]){
    54                 flag=0;
    55                 break;
    56             }
    57         }
    58         if(flag && m==n-1) printf("YES
    ");
    59         else printf("NO
    ");
    60     }
    61 }
  • 相关阅读:
    ELK+Kafka集群日志分析系统
    Centos 6.5 部署 redmine 3.3
    Centos 6.5 搭建l2tp 服务端和客户端
    Logstash之multiline 插件
    MYSQL MHA
    windows上给yii2安装插件
    YII2框架的安装
    Apache服务器配置项和虚拟机配置
    浮点数的比较
    微信自定义菜单总结
  • 原文地址:https://www.cnblogs.com/dilthey/p/7271656.html
Copyright © 2011-2022 走看看