题目:
http://poj.org/problem?id=1308
大意:
给你一堆树枝,让你判断最后能不能构成一棵树。
思路:根据树的定义判断即可
树:
1.入度只能为1或者0(根结点)
2.根结点只有一个
3.出度可以有多个
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> using namespace std; #define MAXN 10010 #pragma comment(linker, "/STACK:102400000,102400000") int pre[10010], son[10010], visit[10010]; int unionsearch(int root) //查找根结点+路径压缩(递归容易破栈) { int root2; root2 = root; while(root != pre[root]) root = pre[root]; while(root2 != root) { int temp = pre[root2]; pre[root2] = root; root2 = temp; } return root; } bool cmp() { int root = 0; for(int i = 0; i < MAXN; ++i) //累计根结点的子节点个数 if(visit[i]) ++son[unionsearch(i)]; for(int i = 0; i < MAXN; ++i) //累计根结点的个数 if(son[i] > 1) root++; if(root > 1) //判断为树或者为森林 return false; else return true; } int main() { //freopen("Input.txt", "r", stdin); int start, end, x, y, flag, T = 0; while(true) { flag = 0; for(int i = 0; i < MAXN; ++i) pre[i] = i; memset(son, 0, sizeof(son)); memset(visit, 0, sizeof(visit)); while(scanf("%d%d", &start, &end) && start && end) { if(start == -1 && end == -1) return 0; x = unionsearch(start); y = unionsearch(end); visit[start] = 1; // 树枝标记,忘了。调试了N久。 visit[end] = 1; if(x == y || end != y) //x == y为环,end == y,入度为2 flag = 1; else pre[end] = start; } if(flag) printf("Case %d is not a tree.\n", ++T); else { if(cmp()) printf("Case %d is a tree.\n", ++T); else printf("Case %d is not a tree.\n", ++T); } } return 0; }
改进后的程序(2011/10/25)
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> using namespace std; #define MAXN 10010 int pre[10010], visit[10010]; int unionsearch(int root) //查找根结点+路径压缩 { int root2; root2 = root; while(root != pre[root]) root = pre[root]; while(root2 != root) { int temp = pre[root2]; pre[root2] = root; root2 = temp; } return root; } bool cmp() { int root = 0; for(int i = 0; i < MAXN; ++i) //累计根结点的子节点个数 if(visit[i] && pre[i] == i) root++; if(root > 1) //判断为树或者为森林 return false; else return true; } int main() { //freopen("Input.txt", "r", stdin); int start, end, x, y, flag, T = 0; while(true) { flag = 0; for(int i = 0; i < MAXN; ++i) pre[i] = i; memset(visit, 0, sizeof(visit)); while(scanf("%d%d", &start, &end) && start && end) { if(start == -1 && end == -1) return 0; x = unionsearch(start); y = unionsearch(end); visit[start] = 1; visit[end] = 1; if(x == y || end != y) flag = 1; else pre[end] = start; } if(flag) printf("Case %d is not a tree.\n", ++T); else { if(cmp()) printf("Case %d is a tree.\n", ++T); else printf("Case %d is not a tree.\n", ++T); } } return 0; }