POJ2699:The Maximum Number of Strong Kings(枚举+贪心+最大流)
The Maximum Number of Strong Kings
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 2488 | Accepted: 1131 |
题目链接:http://poj.org/problem?id=2699
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
题意:
多组数据,然后对于每组数据给出每个人击败的人数,为最多有多少人是强者。
强者的定义为:得到的分数最多 or 击败所有分数比他高的人。这里每击败一个人都可以得一分。
题解:
这题orz...没有想出来。但最后看了题解后发现就是个公平分配问题。
我们建图时比赛在左边,人在右边。每场比赛连两个人,代表这两个人在比赛,然后每场比赛只会分配1的流出去,代表哪个人获胜。
这就是我们建图的大体思路。
由于人数很少,所以我们可以枚举来确定强者,那么怎么确定呢,直接二进制表示的话复杂度太高。
通过证明可以发现,分数越高的人越有可能成为强者,简要证明过程如下:
假设分数为: ...i j k ......,这里i和k时强者,而j不是。如果i是强者,那么说明i打败了后面的所有人,而j不是强者,则说明他可能输给了后面的某几个人。
因为j的分数比i的分数高,说明j多欺负了几个弱者。那么现在我们让j赢回高分的人,让i去赢前面多欺负的那几个人,此时i可能会输给比他强的人,此时满足赢的数量和之前一样。相当于换了人去欺负那些弱者。这样j也可以变为强者了。
以上就是简略的一个证明,只要保证每个人的分数不变就ok。
然后我们从分数大开始枚举,在建图时,源点连接比赛,容量为1;人连接汇点,容量为他能赢的最多次数。
比赛连接两个人时,如果一个人是强者并且另一个人分数比他高,那么只能强者赢;否则哪个赢都可以。对赢的那个人连接容量为1的边。
最后跑个最大流看看比赛能否比完就行了(我这里是通过是否每个人的分数能够符合题意来判断的)。
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
#define s 0
#define t 200
#define INF 0x3f3f3f3f
#define st n*(n-1)/2
using namespace std;
typedef long long ll;
const int N = ;
int T;
char str[N];
int a[N],vis[N],head[N],d[N];
int ans,tot,mx,n,sum;
struct Edge{
int v,c,next;
}e[N*N];
void adde(int u,int v,int c){
e[tot].v=v;e[tot].next=head[u];e[tot].c=c;head[u]=tot++;
e[tot].v=u;e[tot].next=head[v];e[tot].c=;head[v]=tot++;
}
void build(){
memset(head,-,sizeof(head));tot=;
for(int i=;i<=st;i++) adde(s,i,);
int fir = st+,last = st+;
for(int i=;i<=st;i++){
if(vis[fir]&&a[last-st]>a[fir-st]){
adde(i,fir,);adde(i,last,);
}else if(vis[last]&&a[last-st]<a[fir-st]){
adde(i,fir,);adde(i,last,);
}else{
adde(i,fir,);adde(i,last,);
}
last++;
if(last>st+n){
fir++;last=fir+;
}
}
for(int i=st+;i<=st+n;i++) adde(i,t,a[i-st]);
}
bool bfs(int S,int T){
memset(d,,sizeof(d));d[S]=;
queue <int > q;q.push(S);
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u];i!=-;i=e[i].next){
int v=e[i].v;
if(!d[v] && e[i].c>){
d[v]=d[u]+;
q.push(v);
}
}
}
return d[T]!=;
}
int dfs(int S,int a){
int flow=,f;
if(S==t || a==) return a;
for(int i=head[S];i!=-;i=e[i].next){
int v=e[i].v;
if(d[v]!=d[S]+) continue ;
f=dfs(v,min(a,e[i].c));
if(f){
e[i].c-=f;
e[i^].c+=f;
flow+=f;
a-=f;
if(a==) break;
}
}
if(!flow) d[S]=-;
return flow;
}
int Dinic(){
int max_flow=;
while(bfs(,t)) max_flow+=dfs(,INF);
return max_flow;
}
int main(){
cin>>T;
getchar();
while(T--){
memset(vis,,sizeof(vis));
gets(str);
mx=n=sum=;ans=-;
int len = strlen(str);
for(int i=;i<len;i++)
if(str[i]<='' && str[i]>='')
a[++n]=str[i]-'',mx = max(mx,a[n]),sum+=a[n];
for(int i=n;i>=;i--){
if(a[i]==mx) continue ;
vis[i+st]=;
build();
int max_flow=Dinic();
if(max_flow<sum){
ans=n-i;
break ;
}
}
if(ans==-) ans=n;
cout<<ans<<endl;
}
return ;
}
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 tour ...
- POJ2699 The Maximum Number of Strong Kings(最大流)
枚举所有Strong King的状态(最多1024种左右),然后判断是否合法. 判定合法用网络流,源点-比赛-人-汇点,这样连边. 源点向每场比赛连容量为1的边: 如果一场比赛,A和B,A是Stron ...
- poj 2699 The Maximum Number of Strong Kings 枚举 最大流
题目链接 题意 对于一个竞赛图(有向完全图),其顶点是选手,边是比赛,边\(e=(u,v)\)代表该场比赛中\(u\)战胜\(v\). 现定义选手的分数为其战胜的人的个数(即竞赛图中点的出度).并且定 ...
- 【POJ2699】The Maximum Number of Strong Kings(网络流)
Description A tournament can be represented by a complete graph in which each vertex denotes a playe ...
- 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 ...
- 【POJ2699】The Maximum Number of Strong Kings(二分,最大流)
题意: 有n个队伍,两两都有比赛 知道最后每支队伍获胜的场数 求最多有多少队伍,他们战胜了所有获胜场数比自己多的队伍,这些队伍被称为SK N<=50 思路:把每个队伍和它们两两之间的比赛都当做点 ...
- POJ 2699 The Maximum Number of Strong Kings (最大流+枚举)
http://poj.org/problem?id=2699 题意: 一场联赛可以表示成一个完全图,点表示参赛选手,任意两点u, v之间有且仅有一条有向边(u, v)或( v, u),表示u打败v或v ...
- POJ - 2699 The Maximum Number of Strong Kings (最大流+枚举)
题意:有n(n<=10)个选手,两两之间打比赛,共有n*(n-1)/2场比赛,赢一场得1分.给出每个人最后的得分.求有多少个定义如下的strong king:赢了所有得分比自己高的人或本身就是分 ...
- poj 2699 The Maximum Number of Strong Kings【最大流+枚举】
因为n很小所以从大到小枚举答案.(从小到大先排个序,因为显然胜利场次越多越容易成为strong king.然后对于每个枚举出来的ans建图.点分别表示人和比赛.s向所有人连接流量为胜利场次的边,所有比 ...
随机推荐
- 网站标题被篡改成北京赛车、PK10的解决处理办法
客户网站于近日被跳转到赌博网站,打开后直接跳转到什么北京赛车,PK10等内容的网站上去,客户网站本身做了百度的推广,导致所有访问用户都跳转到赌博网站上去,给客户带来很大的经济损失,再一个官方网站的形象 ...
- mysql5.6主主复制及keepalived 高可用
1.实验目的 mysql服务器作为生产环境中使用最广泛的数据库软件,以其开源性,稳定性而广泛使用,但同时由于数据存储,读写频率高,极易造成数据库出错,从而给企业造成不可挽回的损失,我们除了做好数据库的 ...
- 按升序打印X,Y,Z的整数值
#include <stdio.h> #define TRUE 1 #define FALSE 0 int main() { int x,y,z; printf("x: &quo ...
- 动态规划----FatMouse’s Speed(HDU 1160)
参考:https://blog.csdn.net/u012655441/article/details/64920825 https://blog.csdn.net/wy19910326/articl ...
- Druid时序数据库升级流程
目前Druid集群版本为0.11.0,新版本0.12.1已支持Druid SQL和Redis,考虑到Druid新特性以及性能的提升,因此需要将Druid从0.11.0版本升级到0.12.1版本,下面将 ...
- Encrypted bootloader (程序BIN文件加密及在线升级)
了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 在上一个博客随笔,我介 ...
- Java测试工具和框架
个人目前只接触过JUnit以及Powermock,后续会关注更多有关测试这方面的东西 8个超实用的Java测试工具和框架_开发/数据库_IT专家网 http://database.ctocio.com ...
- Java日志(一):log4j与.properties配置文件
日志是应用软件中不可缺少的部分,Apache的开源项目log4j是一个功能强大的日志组件,提供方便的日志记录,在Apache网站jakarta.apache.org/log4j可以免费下载到Log4j ...
- windows下网络命令----Tracert命令详解
现在网络四通八达,网线光纤基站卫星,只要运营商能收费的地方,就有网络,覆盖了全世界所有的区域.彻底改变了以前通讯基本靠吼的情况.那么宽广的网络世界,超过100米就得需要中继放大信号的网线,即使现在的光 ...
- 关于缺失值(missing value)的处理---机器学习 Imputer
关于缺失值(missing value)的处理 在sklearn的preprocessing包中包含了对数据集中缺失值的处理,主要是应用Imputer类进行处理. 首先需要说明的是,numpy的数组中 ...