题意:
给出M组关系,每组描述两个数的大小关系,问根据这些关系,1 - N中哪些数可能是中位数
分析:
容易想到给每组关系建一条有向边表示大小,如果整个图中存在环,那么一定存在矛盾,否则对于每个点能否成为中位数,只需要判断比它大的数的个数和比它小的数的个数是否都小于等于N/2即可,如果其中有一个的数量大于N/2,无论怎么构造都不能使它成为中位数,因为大小关系具有传递性,可以跑一遍Floyed标记那些数的大小关系已经确定,也能方便的统计个数,同时也能判环,如果打算写DFS统计个数,注意算重
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e2+22;
int a[maxn][maxn],in[maxn],out[maxn],T,n,m,u,v;
bool floyed(){
for(int k = 1;k <= n; ++k) //传递关系
for(int i = 1;i <= n; ++i)
for(int j = 1;j <= n; ++j)
if(a[i][k] && a[k][j]) a[i][j] = 1;
for(int i = 1;i <= n; ++i) //判环
for(int j = 1;j <= n; ++j)
if(a[i][j] && a[j][i]) return false;
return true;
}
void solve(){ //统计个数
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
for(int i = 1;i <= n; ++i)
for(int j = 1;j <= n; ++j)
if(a[i][j]) in[j]++,out[i]++;
}
int main(){
cin >> T;
while(T--){
memset(a,0,sizeof(a));
cin >> n >> m;
while(m--){
cin >> u >> v;
a[u][v] = 1;
}
if(floyed()){
solve();
for(int i = 1;i <= n; ++i){
if(in[i] <= n/2 && out[i] <= n/2) putchar('1');
else putchar('0');
}
putchar('\n');
}
else{
for(int i = 1;i <= n; ++i) putchar('0');
putchar('\n');
}
}
return 0;
}