解题报告 之 POJ2699 The Maximum Number of Strong Kings

解题报告 之 POJ2699 The Maximum Number of Strong Kings

Description

A tournament can be represented by a complete graph in which each vertex denotes a player and a directed edge is from vertex x to vertex y if player x beats player y. For a player x in a tournament T, the score of x is the number of players beaten by x. The
score sequence of T, denoted by S(T) = (s1, s2, . . . , sn), is a non-decreasing list of the scores of all the players in T. It can be proved that S(T) = (s1, s2, . . . , sn) is a score sequence of T if and only if 

for k = 1, 2, . . . , n and equality holds when k = n. A player x in a tournament is a strong king if and only if x beats all of the players whose scores are greater than the score of x. For a score sequence S, we say that a tournament T realizes S if S(T)
= S. In particular, T is a heavy tournament realizing S if T has the maximum number of strong kings among all tournaments realizing S. For example, see T2 in Figure 1. Player a is a strong king since the score of player a is the largest score in the tournament.
Player b is also a strong king since player b beats player a who is the only player having a score larger than player b. However, players c, d and e are not strong kings since they do not beat all of the players having larger scores.

The purpose of this problem is to find the maximum number of strong kings in a heavy tournament after a score sequence is given. For example,Figure 1 depicts two possible tournaments on five players with the same score sequence (1, 2, 2, 2, 3). We can see that
there are at most two strong kings in any tournament with the score sequence (1, 2, 2, 2, 3) since the player with score 3 can be beaten by only one other player. We can also see that T2 contains two strong kings a and b. Thus, T2 is one of heavy tournaments.
However, T1 is not a heavy tournament since there is only one strong king in T1. Therefore, the answer of this example is 2.

Input

The first line of the input file contains an integer m, m <= 10, which represents the number of test cases. The following m lines contain m score sequences in which each line contains a score sequence. Note that each score sequence contains at most ten scores.

Output

The maximum number of strong kings for each test case line by line.

Sample Input

5
1 2 2 2 3
1 1 3 4 4 4 4
3 3 4 4 4 4 5 6 6 6
0 3 4 4 4 5 5 5 6
0 3 3 3 3 3

Sample Output

2
4
5
3
5

题目大意:有kase组数据。每组数据有一些人两两比赛,告诉你每个人赢得比赛的次数。如果一个人满足它打败了所有分数严格大于它的那个人,则它成为King;当然分数最高的人们自然也都是King。那么请问这场比赛最多能产生多少King呢?

分析:数据规模小的可怜,至多10组数据,每组数据至多10个人。首先明确一个贪心,就是King一定是比分最高的几个人,因为如果比分低的反而是King那么比分比它高的更容易成为King。然后注意的是不确定的输入我的处理办法是用stringstream提取一行即可。

然后我们用最大流的思路来解决。超级源点与所有选手相连,负载为胜利的次数。首先我们要去试探有几个King的时候满足条件,我采用的是二分,由于规模很小,枚举也行。然后在Kings确定了之后,对于每场比赛也看成一个节点,遍历两两选手i,j。如果i是King且score[j]>score[i],说明这场比赛i一定要赢,那么选手i与这场比赛连接,负载为1。如果不满足以上条件则说明此场胜负无所,选手i
、j 都与这场比赛连接,负载为1。最后再让每场比赛与超级汇点连接,负载为1。再跑最大流看看是否最大流=比赛总数n*(n-1)/2。根据结果二分。(枚举的话从低开始往高找,找到一组解即为最优解)。

上代码:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cstdio>
#include<sstream>
#include<string>
using namespace std;

const int MAXN = 210;
const int MAXM = 41000;
const int INF = 0x3f3f3f3f;

struct Edge
{
	int from, to, cap, next;
};

Edge edge[MAXM];
int level[MAXN];
int head[MAXN];
int score[MAXN];
int bigger[MAXN];
int src, des, cnt;

void addedge( int from, int to, int cap )
{
	edge[cnt].from = from;
	edge[cnt].to = to;
	edge[cnt].cap = cap;
	edge[cnt].next = head[from];
	head[from] = cnt++;

	swap( from, to );

	edge[cnt].from = from;
	edge[cnt].to = to;
	edge[cnt].cap = cap;
	edge[cnt].next = head[from];
	head[from] = cnt++;
}

int bfs()
{
	memset( level, -1, sizeof level );
	queue<int> q;
	while (!q.empty())
		q.pop();
	level[src] = 0;
	q.push( src );

	while (!q.empty())
	{
		int u = q.front();
		q.pop();
		for (int i = head[u]; i != -1; i = edge[i].next)
		{
			int v = edge[i].to;
			if (edge[i].cap&&level[v] == -1)
			{
				level[v] = level[u] + 1;
				q.push( v );
			}
		}
	}
	return level[des] != -1;
}

int dfs( int u, int f )
{
	if (u == des) return f;

	int tem;
	for (int i = head[u]; i != -1; i = edge[i].next)
	{
		int v = edge[i].to;
		if (edge[i].cap&&level[v] == level[u] + 1)
		{
			tem = dfs( v, min( f, edge[i].cap ) );
			if (tem > 0)
			{
				edge[i].cap -= tem;
				edge[i ^ 1].cap += tem;
				return tem;
			}
		}
	}
	level[u] = -1;
	return 0;
}

int Dinic()
{
	int ans = 0, tem;

	while (bfs())
	{
		while (tem = dfs( src, INF ))
		{
			ans += tem;

		}
	}
	return ans;
}

int main()
{
	int kase;
	cin >> kase;
	getchar();
	src = 0; des = 105;

	while (kase--)
	{
		int n = 0;
		string str;
		getline( cin, str );
		stringstream ss( str );
		int sc;

		while (ss >> sc)
		{
			score[++n] = sc;
		}
		bigger[n] = 0;
		for (int i = n - 1; i >= 1; i--)
		{
			if (score[i] == score[i + 1]) bigger[i] = bigger[i + 1];
			else bigger[i] = n - i;
		}

		int start;
		for ( start = 1; start <= n; start++)
		{
			if (score[start] >= bigger[start])break;
		}

		int low = start, high = n;
		int ans = start;
		while(low<=high)
		{
			int mid = (low + high) / 2;
			memset( head, -1, sizeof head );
			cnt = 0;
			int match = 0;
			for (int i = 1; i <= n; i++)
			{
				addedge( src, i, score[i] );
			}

			for (int i = 1; i <= n; i++)
			{
				for (int j = i+1; j <= n; j++)
				{
					if (i >= mid&&score[j] > score[i])
						addedge( i, (++match) + 50, 1 );
					else
					{
						addedge( i, (++match) + 50, 1 );
						addedge( j, match + 50, 1 );
					}
				}
			}

			for (int i = 1; i <= match; i++)
			{
				addedge( i + 50, des, 1 );
			}

			if (Dinic() < (n*(n-1))/2) low = mid + 1;
			else
			{
				ans = mid;
				high = mid - 1;
			}
		}

		cout << n - ans + 1 << endl;
	}
	return 0;
}

洗个澡开始开黑啦~~拜拜

时间: 2024-10-06 17:58:37

解题报告 之 POJ2699 The Maximum Number of Strong Kings的相关文章

POJ2699 The Maximum Number of Strong Kings

Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2102   Accepted: 975 Description A tournament can be represented by a complete graph in which each vertex denotes a player and a directed edge is from vertex x to vertex y if player x beats

【POJ2699】The Maximum Number of Strong Kings

Description A tournament can be represented by a complete graph in which each vertex denotes a player and a directed edge is from vertex x to vertex y if player x beats player y. For a player x in a tournament T, the score of x is the number of playe

POJ2699_The Maximum Number of Strong Kings

这题目,,,真是...诶.坑了好久. 给一个有向图.U->V表示U可以打败V并得一分. 如果一个人的得分最高,或者他打败所有比自己得分高的人,那么此人就是king. 现在给出每个人的得分,求最多可能有多少个king同时存在. 可以证明,如果有k个人是king,那么至少有一种分配方案使得这k个king都是分数最高的那k个人.(证明略,想想就知道了) 于是我们可以开始枚举从i个人开始,后面的都是king. 除了源点和汇点以外,还有两种点,一种表示人(n),一种表示比赛(n*(n/2)/2). 如果一

POJ 2699 The Maximum Number of Strong Kings Description

The Maximum Number of Strong Kings Description A tournament can be represented by a complete graph in which each vertex denotes a player and a directed edge is from vertex x to vertex y if player x beats player y. For a player x in a tournament T, th

【poj2699】 The Maximum Number of Strong Kings

http://poj.org/problem?id=2699 (题目链接) 题意 给出1张有向完全图.U->V表示U可以打败V并得一分.如果一个人的得分最高,或者他打败所有比自己得分高的人,那么此人就是king.现在按顺序给出每个人的得分,求最多可能有多少个king同时存在. Solution 想了半天贪心,然而得分相等的情况真的很不好处理..真的没想到是最大流..左转题解:http://blog.csdn.net/sdj222555/article/details/7797257 考虑这样建图

【POJ2699】The Maximum Number of Strong Kings(二分,最大流)

题意: 有n个队伍,两两都有比赛 知道最后每支队伍获胜的场数 求最多有多少队伍,他们战胜了所有获胜场数比自己多的队伍,这些队伍被称为SK N<=50 思路:把每个队伍和它们两两之间的比赛都当做点,判断最大流是否满流即可 S-->队伍 a[i] 队伍 -->比赛 1 比赛-->T 1 i号队伍是SK:如果j为SK且a[i]>a[j]则j必胜,如果a[i]<a[j]则i必胜 只要必胜者向他们之间的比赛连1条边即可 如果j不为SK,胜负未知,两个点都向他们之间的比赛连1条边

【POJ2699】The Maximum Number of Strong Kings 枚举(二分)+网络流check、

题意: 有n个人,两两都有比赛,然后有每个人的胜场次数. 规定把比自己胜场次数多的人都赢了的就是strong(weak) king (vegetables) (why i say that they are so weak? :****,how do you think a person who beat the heroes but defeated at the dogface? ) 让你安排比赛,问最多有多少个strongking? 题解: 首先(有人说)能证如果有k个sk,那么一定可以是

The Maximum Number of Strong Kings

poj2699:http://poj.org/problem?id=2699 题意:n个人,进行n*(n-1)/2场比赛,赢一场则得到一分.如果一个人打败了所有比他分数高的对手,或者他就是分数最高的,那么他就是strong kind.现在给你每个人的得分,问你最多有多少个strong kind. 题解:自己没有思路,看了别人的题解,才勉强理解了.首先,肯定让得分高的成为strong king,因为概率比较大,然后就是怎建图了.假如,我们已经知道了,有m个strong kind,那么这m个人一定是

【POJ】【2699】The Maximum Number of Strong Kings

网络流/最大流/二分or贪心 题目大意:有n个队伍,两两之间有一场比赛,胜者得分+1,负者得分+0,问最多有几只队伍打败了所有得分比他高的队伍? 可以想到如果存在这样的“strong king”那么一定是胜场较多的队伍……(比他赢得多的队伍num少,而他总共赢得场数times足够多,至少得满足times>=num吧?) 那么我们可以二分/枚举k,表示胜场前k多的队伍是stong king.(这题范围小,只有10支队伍,如果队伍较多我们就需要二分了……) 最最丧心病狂的是!!!出题人TMD卡读入!