# POJ-2699-玄学网络流-The Maximum Number of Strong Kings

（有任何问题欢迎留言或私聊 && 欢迎交流讨论哦

#### 题目：传送门

原题目描述及样例在最下面

每次输入给你一行数字，代表n个人的得分。因为n个人之间一共会进行n*(n-1)/2场比赛。每场比赛必有胜负，胜者得一分。然后输入的得分保证非递减。

问最多有多少人赢了所有得分比自己高的人。规定得分最高的那个人算符合条件。这种人称作king。

### 思路：

居然使用最大流写。。。评论区有人贪心写的，好像是有问题的。然后这题好像可以二进制枚举写，因为n最大为10。

但是你搞懂了之后，这题完全可以最大流写。二进制枚举是没有必要的。看了大神博客之后似懂非懂。觉得应该写个博客日后温故知新。

##### 先随手建个图：

超级源点S向n个选手连边，流量为选手的赢得次数。m (=n*(n-1)/2) 场比赛向超级汇点T连边，流量为1，因为每场比赛只有一个人胜利。
因为具体不知道那个选手赢了那场比赛，所以每个选手都向自己参加的比赛连一条边，流量为1。记得实现给比赛标号。

这样建出来的图跑的最大流一定是n*(n-1)/2，也就是选手得分之和。下面再来考虑如何确定king的数量。

##### 先来讲如何根据这个结论建图，后面解释。

就这样跑最大流，如果最大流等于n*(n-1)/2，则代表k个人是符合的。
因为只有最大流等于所有比赛的场次，才代表所有比赛没有冲突，每个人的得分都得到了满足。

#### AC代码：

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int MAXN = 1e3+5;
const int INF = 0x3f3f3f3f;
typedef long long LL;
struct lp{
int to,nex,cap,flow;
}cw[MAXN*10];
int tol;
int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN];
int n,m;
int ar[MAXN],mp[MAXN][MAXN];
char tools[100000];
void init(){
tol = 0;
}
void add(int u,int v,int w,int rw = 0){
cw[tol].to = v;
cw[tol].cap = w;
cw[tol].flow = 0;
cw[tol].to = u;
cw[tol].cap = rw;
cw[tol].flow = 0;
}
int sap(int start,int end,int N){
memset(gap,0,sizeof(gap));
memset(dep,0,sizeof(dep));
int u = start;
pre[u] = -1;
gap[0] = N;
int ans = 0;
while(dep[start] < N){
if(u == end){
int Min = INF;
for(int i = pre[u]; i != -1;i = pre[cw[i^1].to])
if(Min > cw[i].cap - cw[i].flow)
Min = cw[i].cap - cw[i].flow;
for(int i = pre[u];i != -1;i = pre[cw[i^1].to]){
cw[i].flow += Min;
cw[i^1].flow -= Min;
}
u = start;
ans += Min;
continue;
}
bool flag = false;
int v;
for(int i = cur[u];i != -1;i = cw[i].nex){
v = cw[i].to;
if(cw[i].cap - cw[i].flow && dep[v] + 1 == dep[u]){
flag = true;
cur[u] = pre[v] = i;
break;
}
}
if(flag){
u = v;
continue;
}
int Min = N;
for(int i = head[u];i != -1;i = cw[i].nex)
if(cw[i].cap - cw[i].flow && dep[cw[i].to] < Min){
Min = dep[cw[i].to];
cur[u] = i;
}
gap[dep[u]]--;
if(!gap[dep[u]])return ans;
dep[u] = Min+1;
gap[dep[u]]++;
if(u != start)u = cw[pre[u]^1].to;
}
return ans;
}
int build(int k){
init();
int vs=0,vt=m+1;
for(int i=1;i<=n;++i){
for(int j=i+1;j<=n;++j){
if(i>=n-k+1&&ar[i]<ar[j]){
}else{
}
}
}
return sap(vs,vt,vt+1);
}
void cut(char *s){
int len = strlen(s);
int t = 0;
for(int i = 0; i < len; i++){
if(s[i] >= '0' && s[i] <= '9'){
t = t * 10 + s[i] - '0';
if(i == len - 1 || s[i + 1] == ' '){
ar[++n] = t;
t = 0;
}
}
}
}
int main(){
int T;scanf("%d",&T);
getchar();
while(T--){n=0;
memset(tools,0,sizeof(tools));
gets(tools);
cut(tools);
m=n;
for(int i=1;i<n;++i){
for(int j=i+1;j<=n;++j){
mp[i][j]=mp[j][i]=++m;
}
}
for(int i=n;i>=1;--i){
if(build(i)==n*(n-1)/2){
printf("%d\n",i );
break;
}
}
}
return 0;
}

#### 题目描述：

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

• 评论

• 上一篇
• 下一篇