ZOJ---4124: Median 【传递闭包】

题意:

给出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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值