2049913 2006-08-31 22:34:46 Accepted 1268 C++ 00:00.00 448K St.Crux 题如其名。如何判断一幅图为树? 设x, y是一对父子节点。对每个x, y,都必须满足如下条件。 1.每个节点没有两个父亲。反例p[y] != y,即y已有父节点。 2.没有回路。反例find_set(x) == y,父节点的祖先是子节点。 以上在输入时即可判断。 3.没有森林。遍历p[i],没有两个以上的祖先节点。 在这里,采用了并查集作为数据结构,可以用路径压缩,求得根节点。 #include <cstdio>#include <string> int p[1001], x, y, b[1001], ac, c[1001], k = 1; int find_set(int i){ if(p[i] != i) { p[i] = find_set(p[i]); } return p[i];} void proc(){ int i, t = 0; for(i = 0; i < 1001; i ++) { if(b[i]) { c[find_set(i)] ++; } } for(i = 0; i < 1001; i ++) { if(c[i] > 1) t ++; } if(t > 1) ac = 0;} void init(){ int i; for(i = 0; i <= 1000; i ++) p[i] = i; ac = 1; memset(b, 0, sizeof(b)); memset(c, 0, sizeof(c));} void pt(){ printf("Case %d is ", k ++); if(ac) printf("a tree.\n"); else printf("not a tree.\n");} int main(){ //freopen("in.txt", "r", stdin); init(); while(scanf("%d %d", &x, &y)) { if(x == -1) break; if(x == 0) { proc(); pt(); init(); continue; } b[x] = 1, b[y] = 1; if(p[y] != y || find_set(x) == y) ac = 0; p[y] = find_set(x); } return 0;}

评论