博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj 2699 The Maximum Number of Strong Kings
阅读量:5979 次
发布时间:2019-06-20

本文共 4798 字,大约阅读时间需要 15 分钟。

The Maximum Number of Strong Kings
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 1417 Accepted: 669

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
04092031-9358766b1da9481abe734435fd902000.jpg
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.
04092033-a0800aad3199487f89175ac8b6c06424.jpg

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
建图:(s, i)为源点到每个人的流量,再把每场比赛看成一个点,到达这点的边可能有(i, v), (j, v)两条流量为1的边,(v, t )每场比赛和终点相连接,可以通过控制到v的边来限制只能那个点赢得比赛,因而能得出最大的kings数量。
 
#include <iostream>
#include <sstream>
#include <string>
#include <cstdio>
#include <cstring>
#define maxn 100
#define INF 2000000000
#define max(a, b) a > b ? a : b
#define min(a, b) a < b ? a : b
 
using namespace std;
 
int score[maxn];
int front[maxn];
int pre[maxn];
int dis[maxn];
int gap[maxn];
int cur[maxn];
int index;
int n, total;
 
struct Edge{
    int v;
    int w;
    int next;
}edge[1000];
 
void init(){
    memset( pre, -1, sizeof(pre) );
    index = 0;
}
 
void Add( int u, int v, int w ){
    edge[index].v = v;
    edge[index].w = w;
    edge[index].next = pre[u];
    pre[u] = index++;
 
    edge[index].v = u;
    edge[index].w = 0;
    edge[index].next = pre[v];
    pre[v] = index++;
}
 
int maxflow_Sap( int s, int t ){
    memset( dis, 0, sizeof(dis) );
    memset( gap, 0, sizeof(gap) );
    memcpy( cur, pre, sizeof(cur) );
    int flow = INF, u = s, maxflow = 0, i;
    gap[0] = t+1;
    while ( dis[s] < t+1 ){
        for ( i = cur[u]; i != -1; i = edge[i].next ){
            if ( edge[i].w > 0 && dis[u] == dis[edge[i].v] + 1 ){
                break;
            }
        }
        cur[u] = i;
        if ( cur[u] != -1 ){
            flow = min( flow, edge[i].w );
            front[edge[i].v] = u;
            u = edge[i].v;
            if ( u == t ){
                maxflow += flow;
                for ( i = front[t]; ; i = front[i] ){
                    edge[cur[i]].w -= flow;
                    edge[cur[i]^1].w += flow;
                    if ( i == s ){
                        break;
                    }
                }
                u = s;
                flow = INF;
            }
        }
        else{
            int mindis = t + 1;
            for ( i = pre[u]; i != -1; i = edge[i].next ){
                if ( edge[i].w > 0 && mindis > dis[edge[i].v] + 1 ){
                    mindis = dis[edge[i].v] + 1;
                    cur[u] = i;
                }
            }
            gap[dis[u]]--;
            if ( !gap[dis[u]] ){
                break;
            }
            gap[mindis]++;
            dis[u] = mindis;
            if ( u != s ){
                u = front[u];
            }
        }
    }
    return maxflow;
}
 
int Build( int s, int t ){
    int ans = n-1;
    while ( ans >= 0 ){
        init();
        int cnt = n;
        for ( int i = 1; i <= n; i++ ){
            Add( s, i, score[i] );
            for ( int j = i+1; j <= n; j++ ){
                cnt++;
 
                if ( i > ans && score[j] > score[i] ){        //限制只能i赢
                    Add( i, cnt, 1 );
                }
                else{                                        //i,j都可能赢
                    Add( i, cnt, 1 );
                    Add( j, cnt, 1 );
                }
                Add( cnt, t, 1 );
            }
        }
        if ( n*(n-1)/2 != maxflow_Sap( s, t ) ){
            return n-ans-1;
        }
        ans--;
    }
    return n;
}
 
int main(){
    int T;
    scanf("%d%*c", &T);
    while ( T-- ){
        char c[100];
        gets(c);
        stringstream ss(c);
        int i = 1;
        n = 0;
        while ( ss >> score[i] ){
            total += score[i++];
        }
        n = i - 1;
        printf("%d\n", Build( 0, n*(n-1)/2+n+1 ));
    }
    return 0;
}

转载于:https://www.cnblogs.com/weibingkitty/p/3300324.html

你可能感兴趣的文章
怎么查看linux文件夹下有多少个文件(mac同样)
查看>>
cacti监控一览无余
查看>>
第十六章--访问文件
查看>>
ASP.NET MVC学前篇之Ninject的初步了解
查看>>
对缓存击穿的一点思考
查看>>
Python自动化开发学习15-css补充内容
查看>>
解析find用法
查看>>
JAVA BIO 服务器与客户端实现示例
查看>>
使用Denyhost来阻止恶意连接SSH的IP
查看>>
Java: System.exit() 与安全策略
查看>>
强制杀oracle进程
查看>>
《Cisco IPv6网络实现技术(修订版)》一2.6 配置练习:使用Cisco路由器配置一个IPv6网络...
查看>>
《可穿戴创意设计:技术与时尚的融合》一一第2章 与可穿戴设备有关的故事...
查看>>
ruby动态new对象
查看>>
《JavaScript启示录》——导读
查看>>
如何让你的 Linux 系统干净整洁
查看>>
《JavaScript高效图形编程(修订版)》——6.10 用画布sprites取代DHTMLsprite
查看>>
Linux中grep命令的12个实践例子
查看>>
使用Docker Compose部署基于Sentinel的高可用Redis集群
查看>>
Mybatis 3学习笔记(一)
查看>>