POJ 3310 Caterpillar 并查集+dfs

来源:互联网 发布:淘宝定位在哪里设置 编辑:程序博客网 时间:2024/06/11 20:46

题意:判断一个图是否为树,并且有一条路径使得所有顶点在这条路径上或者这个点相邻的点在路径上。

先用并查集判断是否是一棵树,然后dfs回溯,每次遍历每个节点的所有子节点,然后找一个子节点扩展,看是否能遍历所有点,能就满足条件。

#include <iostream>#include <cstring>#include <cstdio>#include <vector>using namespace std;vector<int> e[105];int vis[105];int ans, anst, n;int find(int u) {    while(~vis[u])        u = vis[u];    return u;}void dfs(int u, int d) {    if(vis[u]) return;    if(++d == n) {        anst = 1;        return;    }    vis[u]++;    int td = 0;    for(int i = 0; i < e[u].size(); i++) {        if(vis[e[u][i]] == 0)            td++;        vis[e[u][i]]++;    }    for(int i = 0; i < e[u].size(); i++) {        vis[e[u][i]]--;        dfs(e[u][i], d + td - 1);        vis[e[u][i]]++;    }    for(int i = 0; i < e[u].size(); i++) {        vis[e[u][i]]--;    }    vis[u]--;}int main() {    int m, i, j, a, b, ks = 1;    while(~scanf("%d%d", &n, &m) && n) {        memset(vis, -1, sizeof(vis));        for(i = 0; i <= n; i++)            e[i].clear();        ans = 1;        anst = 0;        for(i = 0; i < m; i++) {            scanf("%d%d", &a, &b);            e[a].push_back(b);            e[b].push_back(a);            a = find(a);            b = find(b);            if(a == b) {                ans = 0;            }            else vis[a] = b;        }        int t = 0;        for(i = 1; i <= n; i++)            if(vis[i] == -1)                t++;        if(t > 1)            ans = 0;        if(ans) {            memset(vis, 0, sizeof(vis));            for(i = 1; i <= n; i++) {                dfs(i, 0);            }        }        if(ans && anst)            printf("Graph %d is a caterpillar.\n", ks++);        else printf("Graph %d is not a caterpillar.\n", ks++);    }    return 0;}/**881 22 33 44 53 63 76 87 8**/

0 0
原创粉丝点击