Take any directed graph D with n vertices and m edges. You can make the Lying graph E of D in the following way. E will have mvertices, one for each edge of D. For example, if D has an edge uv, then E will have a vertex called uv. Now, whenever D has edgesuv and vw, E will have an edge from vertex uv to vertex vw. There are no other edges in E.
You will be given a graph E and will have to determine whether it is possible for E to be the Lying graph of some directed graph D.
Input
The first line of input gives the number of cases, N (N<220). N test cases follow. Each one starts with two lines containing m (0≤ m≤300) and k. The next k lines will each contain a pair of vertices, x and y, meaning that there is an edge from x to y in E. The vertices are numbered from 0 to m-1
Output
For each test case, output one line containing "Case #x:" followed by either "Yes" or "No", depending on whether E is a valid Lying graph or not. Note that D is allowed to have duplicate edges and self-edges.
Sample Input Output for Sample Input
4 2 1 0 1 5 0 4 3 0 1 2 1 2 3 3 9 0 1 0 2 1 2 1 0 2 0 2 1 0 0 1 1 2 2 | Case #1: Yes Case #2: Yes Case #3: No Case #4: Yes
|
昨天受凉了,上吐下泻,今天状态好差,头好痛。。。做不动题,学会其他的。
检查全部,对于E中的几点v,所有指向v的结点,这些结点必然指向同一个集合。
AC代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <string>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <stack>
#include <queue>
#include <bitset>
#include <cassert>
#include <cmath>
#include <functional>
using namespace std;
int g[305][305], gt[305];
int invg[305][305], invgt[305], to[305];
int n, m;
bool check() {
int j, k;
for (int i = n - 1; i >= 0; i--) {
for (j = 0; j < n; j++) to[j] = 0;
for (j = invgt[i] - 1; j >= 0; j--) {
for (k = gt[invg[i][j]] - 1; k >= 0; k--) {
to[g[invg[i][j]][k]]++;
}
}
for (j = 0; j < n; j++) {
if (to[j] == 0 || to[j] == invgt[i]) {
}
else {
return false;
}
}
}
return true;
}
int main()
{
ios::sync_with_stdio(false);
int kase= 0;
int T;
cin >> T;
while (T--) {
memset(gt, 0, sizeof(gt));
memset(invgt, 0, sizeof(gt));
cin >> n >> m;
int x, y;
while (m--) {
cin >> x >> y;
g[x][gt[x]++] = y;
invg[y][invgt[y]++] = x;
}
bool flag = check();
cout << "Case #" << ++kase << ": " << (flag ? "Yes\n" : "No\n");
}
return 0;
}