[CQOI2013]图的逆变换
题解懒得写 转自 http://tisu.is-programmer.com/posts/38862.html
如果在新图中存在 i->k 和 j->k
那么在原图里一定是这样的
所以我们可以发现,如果存在i->k和j->k
但只存在i->t或j->t其中之一,则新图不合法。
mycode:
/** * Problem:Inverse * Author:Shun Yao * Time:2013.5.27 * Result:Accepted */ #include <cstring> #include <cstdlib> #include <cstdio> using namespace std; long tot; class gnode { public: long v; gnode *next; gnode() {} ~gnode() {} gnode(long V, gnode *ne):v(V), next(ne) {} } *g[305], G[90005]; void add(long x, long y) { g[x] = &(G[tot++] = gnode(y, g[x])); } long f[305], s[305]; int main() { long T, n, m, i, j, k, x, y; char ff; gnode *e; freopen("inverse.in", "r", stdin); freopen("inverse.out", "w", stdout); scanf("%ld", &T); while (T--) { scanf("%ld%ld", &n, &m); for (i = 0; i < n; ++i) g[i] = 0; tot = 0; for (i = 1; i <= m; ++i) { scanf("%ld%ld", &x, &y); add(x, y); } memset(f, -1, sizeof f); memset(s, 0, sizeof s); ff = 1; for (i = 0; i < n; ++i) if (g[i]) { j = f[g[i]->v]; k = 0; for (e = g[i]; e; e = e->next) if (f[e->v] == j) ++k; else { ff = 0; break; } if (j == -1) { for (e = g[i]; e; e = e->next) { f[e->v] = i; s[e->v] = k; } } ff = ff && s[g[i]->v] == k; if (!ff) break; } if (!ff) puts("No"); else puts("Yes"); } fclose(stdin); fclose(stdout); return 0; }
作者:HSUPPR
出处:http://www.cnblogs.com/hsuppr/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出
原文链接,否则保留追究法律责任的权利。