题解 CF690C1

题目大意:

给定一张 \(n\) 个点 \(m\) 条边的无向图,判断这是不是一棵树。

题目分析:

两种思路:

思路一:

不需要建图,直接使用并查集判环即可

最后判断一下图联不联通就行,具体方法就是看并查集中是不是 \(fa_x = x\) 的情况只存在一个,或者看边数是否等于 \(n-1\)

时间复杂度 \(O(n + m \log n)\)

思路二:

建图,用 \(dfs\) 判环。

时间复杂度 \(O(n + m)\)

这里给出思路一的代码供大家参考。

代码实现:

#include <bits/stdc++.h>
#define debug(x) cerr<<#x<<": "<<x<<endl;
#define int long long
using namespace std;

inline int read()
{
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}

namespace Larry76{
    const int MAX_SIZE = 1.1e5;
    int fa[MAX_SIZE];
    int getfa(int x){
        if(fa[x]==x)
            return fa[x];
        return fa[x] = getfa(fa[x]);
    }
    void merge(int x,int y){
        int fx = getfa(x);
        int fy = getfa(y);
        fa[fy] = fx;
    }
    void main(){
        //Code Here;
        int n,m;
        cin>>n>>m;
        for(int i=1;i<=n;i++)
            fa[i] = i;
        while(m--){
            int u,v;
            cin>>u>>v;
            if(getfa(u)==getfa(v)){
                cout<<"no"<<endl;
                return;
            }
            merge(u,v);
        }
        int same = 0;
        for(int i=1;i<=n;i++)
            if(fa[i] == i)
                same ++;
        if(same>1)
            cout<<"no"<<endl;
        else
            cout<<"yes"<<endl;
    }
}

signed main(){
#ifdef LOCAL
    freopen("in.in","r",stdin);
    freopen("out.out","w",stdout);
    double c1 = clock();
#else
    ios::sync_with_stdio(false);
#endif
//============================================
    Larry76::main();
//============================================
#ifdef LOCAL
    double c2 = clock();
    cerr<<"Used Time: "<<c2-c1<<"ms"<<endl;
    if(c2-c1>1000)
        cerr<<"Warning!! Time Limit Exceeded!!"<<endl;
    fclose(stdin);
    fclose(stdout);
#endif
    return 0;
}
posted @ 2023-02-17 16:09  Larry76  阅读(15)  评论(0)    收藏  举报