[CQOI2013]图的逆变换

题解懒得写 转自 http://tisu.is-programmer.com/posts/38862.html

如果在新图中存在 i->k 和 j->k

那么在原图里一定是这样的

[CQOI2013]图的逆变换

所以我们可以发现,如果存在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;

}

 

 

你可能感兴趣的:(c)