POJ - 1308 Is It A Tree?(并查集+dfs)

来源:互联网 发布:图书馆可视化数据工具 编辑:程序博客网 时间:2024/06/07 07:23

题目大意:给出你N条有向边,问能否形成一棵树

解题思路:并查集查看每个点是否在都连通,然后dfs判断是否有环
有特例, 0 0的时候是一棵树

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 100010;const int INF = 0x3f3f3f3f;int f[N], head[N];int u, v, cas = 1, Min, Max, tot;bool vis[N];struct Edge{    int v, next;    Edge() {}    Edge(int v, int next): v(v), next(next) {}}E[N];int find(int x) {    return x == f[x] ? x : f[x] = find(f[x]);}void AddEdge(int u, int v) {    E[tot] = Edge(v, head[u]);    head[u] = tot++;}bool dfs(int u) {    vis[u] = true;    for (int i = head[u]; ~i; i = E[i].next) {        int v = E[i].v;        if (vis[v]) return false;        if (!dfs(v)) return false;    }    return true;}void solve() {    memset(head, -1, sizeof(head));    tot = 0;    for (int i = 0; i < N; i++)        f[i] = i;    AddEdge(u, v);    vis[u] = vis[v] = true;    Max = -INF, Min = INF;    Max = max(max(Max, u), v);    Min = min(min(Min, u), v);    if (u == 0 || v == 0) {        printf("Case %d is a tree.\n", cas++);        return ;    }    f[find(v)] = find(u);    while (scanf("%d%d" ,&u, &v) && u + v) {        AddEdge(u, v);        vis[u] = vis[v] = true;        int tx = find(u);        int ty = find(v);        if (tx != ty)            f[ty] = tx;        if (u < Min || v < Min)            Min = min(u, v);        if (u > Max || v > Max)            Max = max(u, v);    }    bool flag = false;    int root = find(Min);    for (int i = Min; i <= Max; i++) {        if (find(i) != root && vis[i]) {            flag = true;            break;        }    }    if (!flag) {        memset(vis, 0, sizeof(vis));        if (!dfs(root))            printf("Case %d is not a tree.\n", cas++);        else            printf("Case %d is a tree.\n", cas++);    }    else {        printf("Case %d is not a tree.\n", cas++);    }}int main() {    while (scanf("%d%d", &u, &v) != EOF) {        if (u == -1 && v == -1) break;        solve();    }    return 0;}
0 0
原创粉丝点击