[图论] 珍珠BEAD

来源:互联网 发布:linux dd命令安装系统 编辑:程序博客网 时间:2024/05/16 00:43

珍珠BEAD

题目描述

有n颗形状和大小都一致的珍珠,它们的重量都不相同。n为整数,所有的珍珠从1到n编号。你的任务是发现哪颗珍珠的重量刚好处于正中间,即在所有珍珠的重量中,该珍珠的重量列(n+1)/2位。

下面给出将一对珍珠进行比较的办法: 给你一架天平用来比较珍珠的重量,我们可以比出两个珍珠哪个更重一些,在作出一系列的比较后,我们可以将某些肯定不具备中间重量的珍珠拿走。   

例如,下列给出对5颗珍珠进行四次比较的情况:

1、珍珠2比珍珠1重   2、珍珠4比珍珠3重   3、珍珠5比珍珠1重   4、珍珠4比珍珠2重   

根据以上结果,虽然我们不能精确地找出哪个珍珠具有中间重量,但我们可以肯定珍珠1和珍珠4不可能具有中间重量,因为珍珠2、4、5比珍珠1重,而珍珠1、2、3比珍珠4轻,所以我们可以移走这两颗珍珠。 写一个程序统计出共有多少颗珍珠肯定不会是中间重量。

输入描述

第一行包含两个用空格隔开的整数N和M,其中1<=N<=99,且N为奇数,M表示对珍珠进行的比较次数,接下来的M行每行包含两个用空格隔开的整数x和y,表示珍珠x比珍珠y重。

输出描述

仅一行包含一个整数,表示不可能是中间重量的珍珠的总数。

样例输入

5 4
2 1
4 3
5 1
4 2

样例输出

2












































【大意】有N个珍珠(N为奇数),给出M次比较,问有多少颗不可能是中间重量(第(N+1)/2重).

【解法】通过数据处理,算出每个珍珠比多少颗珍珠重、轻,若超过一半的珍珠比它轻,则不可能是最中间的数

#include <iostream>using namespace std;int N, M, cnt;int Biger[1001][1001]; //Biger[i][j]=1 表示i比j大int Smaller[1001][1001]; //Smaller[i][j]=1 表示i比j小int Big[1001]; //Big[i]表示比i大的有多少个int Small[1001]; //Big[i]表示比i小的有多少个int main() {int a, b;cin >> N >> M;for(int i=1; i<=M; i++) {cin >> a >> b;Biger[a][b] = Smaller[b][a] = 1;}for(int i=1; i<=N; i++) {for(int j=1; j<=N; j++) {if(Biger[i][j]) { //if i比j大for(int k=1; k<=N; k++)if(Biger[j][k]) //if j比k大Biger[i][k] = Smaller[k][i] = 1; //then i比k大(传递)} else if(Smaller[i][j]) { //if i比j小 同上 for(int k=1; k<=N; k++)if(Smaller[j][k])Smaller[i][k] = Biger[k][i] = 1;}}}for(int i=1; i<=N; i++)for(int j=1; j<=N; j++) {if(Biger[i][j]) Big[i] ++;else if(Smaller[i][j]) Small[i] ++;}for(int i=1; i<=N; i++)if(Big[i] >= (N+1)/2 || Small[i] >= (N+1)/2) cnt ++; //如果超过一半比i小/大,i一定不是最中间重量cout << cnt << endl;return 0;}