题解懒得写 转自 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;
}