zoj-4124 Median

Recall the definition of the median of elements where is odd: sort these elements and the median is the

-th largest element.

In this problem, the exact value of each element is not given, but relations between some pair of elements are given. The -th relation can be described as , which indicates that the -th element is strictly larger than the -th element.

For all , is it possible to assign values to each element so that all the relations are satisfied and the -th element is the median of the elements?

Input

There are multiple test cases. The first line of the input contains an integer , indicating the number of test cases. For each test case:

The first line contains two integers and (, ), indicating the number of elements and the number of relations. It's guaranteed that is odd.

For the following lines, the -th line contains two integers and , indicating that the -th element is strictly larger than the -th element. It guaranteed that for all , or .

It's guaranteed that the sum of of all test cases will not exceed .

Output

For each test case output one line containing one string of length . If it is possible to assign values to each element so that all the relations are satisfied and the -th element is the median, the -th character of the string should be '1', otherwise it should be '0'.

 

看到两点之间有关系的时候,第一反应是拓扑排序,想着求出可能的顺序。

通过分析,发现了 一个点可以当做中点 的条件是 上面点的数量下面点的数量 存在相等的可能。

拓扑排序:有两种关系,一种就是确定的关系一种是不确定的关系

图中给出的都是确定的关系,我们只关心确定的关系有多少,【也就是求  含有 点 \large X  的图中 有多少个点,这些点都是和\large X 确定关系的 】

\large n_{1} : 肯定比\large X 大 的有多少点

\large n_{2}:  肯定比\large X 小 的有多少点

对于其他和\large X 不确定关系的点,他们可以放在上面,也可以放在下面。

 

填充的时候,如果  \large \left | n_{1}-n_{2} \right | 的绝对值,小于等于不确定关系的点,我们就可以填充,或者\large n_{1},n_{2} 都小于  \large \frac{n}{2}

 

只需要求出\large n1,n2 即可,通过dfs求出

【注:判断环的时候,要注意是正在访问的点,不是已经访问完成的点

#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
#define rep(i,a,b) for(int i=a;i<b;++i)

int n,m;

const int N=110;
vector<int> Edge[N];
vector<int> OEdge[N]; 
int vis[N];

int n1,n2;
int wrong;

void dfs(int x){
	vis[x]=1;
	for(int i=0;i<Edge[x].size();i++){
		int v=Edge[x][i];
		if(vis[v]==1){
			wrong=1;return;
		}
		if(vis[v]==-1){
			n1++;
			dfs(v);
		}
	}
	vis[x]=0;
}

void Odfs(int x){
	vis[x]=1;
	for(int i=0;i<OEdge[x].size();i++){
		int v=OEdge[x][i];
		if(vis[v]==1){
			wrong=1;return;
		}
		if(vis[v]==-1){
			n2++;
			Odfs(v);
		}
	}
	vis[x]=0;
}
/*
2
5 4
1 2
3 2
2 4
2 5

3 2
1 1
2 3

7 8
1 2
1 3
2 4
3 4
4 5
4 7
5 6
7 6

3 0

4 4
1 2
1 3
2 4
3 4
*/

int main(){
	int T;
	scanf("%d",&T);
	rep(kase,0,T){
		
		scanf("%d %d",&n,&m);
		rep(i,1,n+1){
			Edge[i].clear();
			OEdge[i].clear();
			vis[i]=-1;
		}
		
	    wrong=0;
		rep(i,0,m){
			int u,v;
			scanf("%d %d",&u,&v);
			Edge[u].push_back(v);
			OEdge[v].push_back(u);
			if(u==v)wrong=1;
		}			
		
		rep(i,1,n+1){
			
			n1=0,n2=0;
			rep(j,1,n+1)vis[j]=-1;
			dfs(i);
			
			rep(j,1,n+1)vis[j]=-1;
			Odfs(i);
			
			int t=n-n1-n2-1;
	
		//	printf("wrong:%d n1:%d %d\n",wrong,n1,n2);
			if(!wrong&&t>=abs(n1-n2)){
				printf("1");
			}else{
				printf("0");
			}
		} 	
		printf("\n");
	}
	return 0;
}

 

 

也可以通过传递闭包的方式,将关系传递给所有可以确定的有序对。

利用warshall算法。

#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
#define rep(i,a,b) for(int i=a;i<b;++i)

const int N=110;
int mat[N][N],res[N];

/*
100
5 4
1 2
3 2
2 4
2 5

3 2
1 1
2 3
*/
int main(){
	int T;
	scanf("%d",&T);
	rep(kase,0,T){
		
		int n,m;
		scanf("%d %d",&n,&m);
		
		rep(i,1,n+1){
			rep(j,1,n+1)mat[i][j]=0;
		}
		rep(i,0,m){
			int u,v;
			scanf("%d %d",&u,&v);
			mat[u][v]=1;
		}
		
		rep(k,1,n+1){
			rep(i,1,n+1){
				rep(j,1,n+1){
					mat[i][j]=mat[i][j]|(mat[i][k]&mat[k][j]);
				}
			}
		}
		
		/*
		rep(i,1,n+1){
			rep(j,1,n+1)printf("%d",mat[i][j]);
			printf("\n");
		}
		*/
		
		int wrong=0;
		rep(i,1,n+1){
			if(mat[i][i]==1){
				wrong=1;break;
			}
			int n1=0,n2=0;
			rep(j,1,n+1){
				if(mat[i][j]&mat[j][i]){
					wrong=1;break;
				}
				if(mat[i][j])n1++;
				if(mat[j][i])n2++;
			}
			if(n-n1-n2-1>=abs(n1-n2))res[i]=1;
			else res[i]=0;
		}
		
		if(wrong)rep(i,0,n)printf("0");
		else rep(i,1,n+1)printf("%d",res[i]);
		
		printf("\n");
	}
	return 0;
}

 

错误点:

1.忘记初始化

2.环的判断错误

3.代码位置不当,导致问题。

4.没看时间复杂度。

 

思路:

当时关注点没在 一点上,想图有多少种情况,想着想着就蒙了,该考虑核心的 中点

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值