这个题感觉很坑,光题面上就有一个地方没说明白; 先建图判一下拓扑序列,合法的话就对每个点进行爆搜。搜下大于它的点的个数和小于它的点的个数,都小于(n + 1) / 2就输出1, 否则输出0; 坑点1:dfs搜的时候必须判断这个点有没有在本次搜过,否则会tle 坑点2:注意审题
using namespace std;
const int N = 110;
vector<int> g[N], gg[N];
int d[N];
int n, m;
bool st1[N], st2[N];
bool bfs() {
queue<int> q;
int cnt = 0;
for(int i = 1; i <= n; i ++ )
if(d[i] == 0) q.push(i), cnt ++;
while(!q.empty()) {
int t = q.front();
q.pop();
for(auto it : g[t]) {
d[it] --;
if(d[it] == 0) {
q.push(it);
cnt ++;
}
}
}
if(cnt == n) return true;
else return false;
}
int ddfs(int u) {
int cnt = 0;
st1[u] = 1;
for(int v : g[u]) {
if(!st1[v]) {
cnt += ddfs(v) + 1;
}
}
return cnt;
}
int udfs(int u) {
int cnt = 0;
st2[u] = 1;
for(int v : gg[u]) {
if(!st2[v]) {
cnt += udfs(v) + 1;
}
}
return cnt;
}
int main()
{
int T;
scanf("%d", &T);
while(T -- ) {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i ++ ) g[i].clear(), d[i] = 0, gg[i].clear();
while(m -- ) {
int a, b;
scanf("%d%d", &a, &b);
g[a].push_back(b);
gg[b].push_back(a);
d[b] ++;
}
bool has = bfs();
//cout << has << endl;
if(has) {
for(int i = 1; i <= n; i ++ ) {
memset(st1, 0, sizeof st1), memset(st2, 0, sizeof st2);
if(udfs(i) <= n / 2 && ddfs(i) <= n / 2) {
putchar('1');
}
else putchar('0');
}
}
else {
for(int i = 1; i <= n; i ++ ) putchar('0');
}
putchar('\n');
}
return 0;
}