美文网首页
POJ1308(Is It A Tree?)

POJ1308(Is It A Tree?)

作者: kimoyami | 来源:发表于2018-11-01 23:31 被阅读5次

链接:https://vjudge.net/problem/POJ-1308
思路:放在并查集专题的,思路是每次合并两个点,如果之前已经合并过了那么一定不能构成一棵树,完成之后检查集合的个数是否为1(即图是否连通)。我这题就想换一个写法,没想到关于树的东西还是一直写不好,到处wa,细节抠不好,所以写篇文章总结下坑点:
1、一定要注意空树、单个点、一条链等特殊情况
2、一定要注意是否需要判断图是否连通!(各大赛区已经有很多人栽在这同一个坑点上了)
3、注意是有向边还是无向边,有向边的树上dfs不需要加父节点判断,而无向边一般是需要的(对比这个专题的最后两个题)。
代码:

#include<cstdio>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 1e5+100;
int vis[maxn],mark[maxn];
vector<int> G[maxn];
int in[maxn];

int a,b;
int flag;

void dfs(int u){
    vis[u] = 1;
    for(int i=0;i<G[u].size();i++){
        int v = G[u][i];
        if(vis[v]){
            flag = 0;
            return;
        }
        dfs(v);
    }
}

int main(){
    int kase = 0;
    flag = 1;
    int maxv = 0;
    int times = 0;
    while(scanf("%d%d",&a,&b)){
        if((a==0&&b==0)||(a==-1&&b==-1)){
            if(a==-1)break;
            printf("Case %d ",++kase);
            if(times==0){//判断空树的情况(又被坑了!!!)
                printf("is a tree.\n");
                continue;
            }
            int num = 0;
            for(int i=1;i<=maxv;i++){//找入度为0的点的个数(根节点),不等于1则无解
                if(mark[i]&&!in[i])num++;
            }
            if(num!=1)flag = 0;
            else{
        for(int i=1;i<=maxv;i++){
            if(mark[i]&&in[i]==0){//找根节点做一次dfs,如果是树连通则一定可以遍历所有节点
                dfs(i);
                break;
            }
        }
        for(int i=1;i<=maxv;i++){
            if(mark[i]&&!vis[i])flag = 0;//如果有节点没有被遍历到(不连通),则无法构成树
        }
        }
        if(flag)printf("is a tree.\n");
        else printf("is not a tree.\n");
            for(int i=1;i<=maxv;i++){
                G[i].clear();
            }
            memset(vis,0,sizeof(vis));
            memset(mark,0,sizeof(mark));
            memset(in,0,sizeof(in));
            maxv = 0;
            flag = 1;
            times = 0;
           continue;
        }
        G[a].push_back(b);
        in[b]++;
        maxv = max(maxv,max(a,b));
        mark[a] = 1;
        mark[b] = 1;
        times++;
    }
    return 0;
}

相关文章

网友评论

      本文标题:POJ1308(Is It A Tree?)

      本文链接:https://www.haomeiwen.com/subject/vqgfxqtx.html