2753473 2008-02-17 16:25:45 Accepted 2740 C++ 00:00.00 436K C.D. 世界上最郁闷的事情,不是连续五个WA,而是连续莫名其妙的WA,却不知道错在哪里;比这更郁闷的事情,是改动之后的连续五个AC,却发现再也找不到刚才究竟错在哪里…… 遥想当年,浙大初赛时,雄姿英发;谈笑间,代码灰飞烟灭。故题重做,多情应笑我,迟来三年。卡了近三年的题目,回过头来再看也是一道简单题。 求图是否为连通生成树。预处理边数M,然后用并查集检查一下是否有回路,马上就可以解决。 因为满足生成树的情况下,M恒等于点数N-1,所以在预处理后就不需要考虑是否所有点都能够被访问。开始的时候写了一个BFS算法,遍历,结果失败。(我果然还是比较菜……= =) #include <cstdio>#include <string>int N, M, p[1001], num[1001];int init ();void init_set ();int find_set ( int );int union_set ( int, int );int main (){ //freopen ( "in.txt", "r", stdin ); while ( init () ) { } return 0;}void init_set (){ int i; for ( i = 1; i <= N; i ++ ) { p[i] = i; num[i] = 1; }}int find_set ( int x ){ int pre = x; while ( p[pre] != pre ) { pre = p[pre]; } int root = pre; while ( x != root ) { int t = p[x]; p[x] = root; x = t; } return root;}int union_set ( int x1, int x2 ){ int p1 = find_set ( x1 ); int p2 = find_set ( x2 ); if ( p1 == p2 ) { return 0; } if ( num[p1] > num[p2] ) { num[p2] += num[p1]; p[p1] = p2; } else { num[p1] += num[p2]; p[p2] = p1; } return 1;}int init (){ scanf ( "%d %d", &N, &M ); if ( N == 0 ) return 0; int i, ac = 1; if ( N != M + 1 ) { printf ( "No\n" ); for ( i = 0; i < M; i ++ ) { int x, y; scanf ( "%d %d", &x, &y ); } } else { init_set (); for ( i = 0; i < M; i ++ ) { int x, y; scanf ( "%d %d", &x, &y ); if ( union_set ( x, y ) == 0 ) { ac = 0; } } if ( ac ) { printf ( "Yes\n" ); } else { printf ( "No\n" ); } } return N;}

评论