POJ2699 The Maximum Number of Strong Kings
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 2102 | Accepted: 975 |
Description
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
Output
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
Source
网络流 最大流
将代表每场比赛的边记为流量图中的点,从S到每场比赛连边,容量为1;
从每个参赛者到T连边,容量为胜利场数。
假设king是胜场最多的前king个人,将参赛者a[]按胜利次数从大到小排序,方便连边。枚举或者二分king数量(n<=10,复杂度没啥差别),对于每场比赛,如果其中一方a是king,且另一方b胜场更多,那么将边强行定向,从比赛到a连边,容量为1(表示胜利);否则a和b都可以胜利,就将边看作双向边,比赛到a、b各连一条边,容量为1。
↑如果能跑满流,那么当前选取的king个数可行。
(测试数据格式似乎很诡异,以下代码中,如果读入方式换成注释掉的部分,本地手测都能过,交上去就WA)
刚开始有另一种设想:
将参赛者拆点,S到每个入点连边,容量为此人胜场a[i],每个出点到T连边,容量为此人负场n-1-a[i]。
枚举king的个数,每多加一个人,就在前一步的参量网络上添边,看网络流能否增广,能就继续加king人数。
但是这种算法在测discuss里的大数据时就挂掉了。
↑姑且记个思路。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<vector>
#define LL long long
using namespace std;
const int mx[]={,,,-,};
const int my[]={,,,,-};
const int mxn=;
int a[mxn],n=;
int cmp(const int q,const int e){return q>e;}
void read(){
char s[];
/* fgets(s,200,stdin);
int len=strlen(s);
for(int i=0;i<len;i++){
int x=0,f=1;char ch=s[i];
while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=s[++i];}
while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=s[++i];}
a[++n]=x;
}*/
gets(s);
int len=strlen(s);
for(int i=;i<len;i++){
if(s[i]>='' && s[i]<='')a[++n]=(s[i]-'');
}
return;
}
struct edge{int v,nxt,f;}e[mxn*mxn*];
int hd[mxn],mct=;
inline void add_edge(int u,int v,int f){
e[++mct].v=v;e[mct].f=f;e[mct].nxt=hd[u];hd[u]=mct;return;
}
inline void ins(int u,int v,int f){add_edge(u,v,f);add_edge(v,u,);return;}
int S,T;
int id[][];
int bct=;
void init(){
memset(hd,,sizeof hd);
n=;mct=;bct=;
return;
}
void init2(){
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++)
id[i][j]=id[j][i]=++bct;
return;
}
int d[mxn];
bool BFS(){
memset(d,,sizeof d);
queue<int>q;
d[S]=;
q.push(S);
while(!q.empty()){
int u=q.front();q.pop();
for(int i=hd[u];i;i=e[i].nxt){
int v=e[i].v;
if(!d[v] && e[i].f){
d[v]=d[u]+;
q.push(v);
}
}
}
return d[T];
}
int DFS(int u,int lim){
if(u==T)return lim;
int tmp,f=;
for(int i=hd[u];i;i=e[i].nxt){
int v=e[i].v;
if(d[v]==d[u]+ && e[i].f){
tmp=DFS(v,min(lim,e[i].f));
e[i].f-=tmp;
e[i^].f+=tmp;
f+=tmp;
lim-=tmp;
if(!lim)return f;
}
}
d[u]=;
return f;
}
int Dinic(){
int res=;
while(BFS())res+=DFS(S,1e9);
return res;
}
int smm=;
bool solve(int lim){
int i,j;
memset(hd,,sizeof hd);
mct=;
for(i=;i<=smm;i++)ins(S,i,);
for(i=;i<=n;i++)ins(smm+i,T,a[i]);//胜场
int hd=;
for(i=;i<=n;i++)
for(j=;j<=i;j++){
if(i==j)continue;
if(i<=lim && a[i]<a[j])ins(id[i][j],smm+i,);
else{
ins(id[i][j],smm+i,);
ins(id[i][j],smm+j,);
}
}
if(Dinic()==smm)return ;
return ;
}
int m;
int main()
{
scanf("%d\n",&m);
int i,j;
while(m--){
init();//
read();
sort(a+,a+n+,cmp);
init2();
// for(i=1;i<=n;i++)printf("%d ",a[i]);
// printf("\n");
smm=;
for(i=;i<=n;i++)smm+=a[i];
if(smm!=n*(n-)/){printf("0\n");continue;}
smm=n*(n-)/;
S=;T=smm+n+;
int ans=;
for(i=;i<=n;i++){
if(solve(i))ans=i;
else break;
}
printf("%d\n",ans);
}
return ;
}
POJ2699 The Maximum Number of Strong Kings的更多相关文章
- POJ2699:The Maximum Number of Strong Kings(枚举+贪心+最大流)
The Maximum Number of Strong Kings Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2488 ...
- POJ2699 The Maximum Number of Strong Kings(最大流)
枚举所有Strong King的状态(最多1024种左右),然后判断是否合法. 判定合法用网络流,源点-比赛-人-汇点,这样连边. 源点向每场比赛连容量为1的边: 如果一场比赛,A和B,A是Stron ...
- 【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 思路:把每个队伍和它们两两之间的比赛都当做点 ...
- 【poj2699】 The Maximum Number of Strong Kings
http://poj.org/problem?id=2699 (题目链接) 题意 给出1张有向完全图.U->V表示U可以打败V并得一分.如果一个人的得分最高,或者他打败所有比自己得分高的人,那么 ...
- The Maximum Number of Strong Kings
poj2699:http://poj.org/problem?id=2699 题意:n个人,进行n*(n-1)/2场比赛,赢一场则得到一分.如果一个人打败了所有比他分数高的对手,或者他就是分数最高的, ...
- 【POJ】【2699】The Maximum Number of Strong Kings
网络流/最大流/二分or贪心 题目大意:有n个队伍,两两之间有一场比赛,胜者得分+1,负者得分+0,问最多有几只队伍打败了所有得分比他高的队伍? 可以想到如果存在这样的“strong king”那么一 ...
- POJ 2699 The Maximum Number of Strong Kings (最大流+枚举)
http://poj.org/problem?id=2699 题意: 一场联赛可以表示成一个完全图,点表示参赛选手,任意两点u, v之间有且仅有一条有向边(u, v)或( v, u),表示u打败v或v ...
随机推荐
- 用微信小程序做H5游戏尝试
微信小程序发布后,公司虽然没有拿到第一批内测资格,但作为微信亲密合作伙伴,一定要第一时间去尝试啦.现在微信小程序刚发布还在测试阶段,可以说是1.0版本,所以框架和结构内容都还不多,相关的文档跟微信AP ...
- 实验二 Java面向对象程序设计
实验二 Java面向对象程序设计 实验内容 1. 初步掌握单元测试和TDD 2. 理解并掌握面向对象三要素:封装.继承.多态 3. 初步掌握UML建模 4. 熟悉S.O.L.I.D原则 5. 了解设计 ...
- TensorFlow 源代码初读感受
把自己微博发的文章:http://www.weibo.com/1804230372/En7PdlgLb?from=page_1005051804230372_profile&wvr=6& ...
- Pathoto项目:AWS+golang+beego搭建
帮兄弟写了一个网站,由于要在国外使用,选择了AWS作为服务器. 不知道后面的价格如何,12个月免费的确吸引了我. 花费3天时间,从注册到服务器搭建访问,终于搞定了.下面记录一下其中容易出错的命令. 1 ...
- C#操作Excel时的格式设定(转)
Excel报表打印的格式设定 1. 表头的设置 Excel._Worksheet myWorksheet; myWorksheet.PageSetup.Orientation = Excel. ...
- Android帧动画
通过播放一张一张图片来实现一段动画 首先配置anim.xml: <?xml version="1.0" encoding="utf-8"?> < ...
- linux 防火墙开放特定端口与指定ip谨防
vi etc/iptable/sysconfig/iptables linux 开放固定端口 -A INPUT -m state --state NEW -m tcp -p tcp --dport 1 ...
- stack 栈的实现
今天晚上去「南哪」听了场AI的讲座,除了话筒真心不给力之外,算是对微软这方面的进展有了更多了解,毕竟是半宣传性质的活动吧. 光听这些是没用的,眼下还是打好基础,多尝试学点新技术,拓宽能力和视野比较重要 ...
- 1020关于mysql一个简单语句的执行流程
MySQL的语句执行顺序 转自http://www.cnblogs.com/rollenholt/p/3776923.html MySQL的语句一共分为11步,如下图所标注的那样,最先执行的总是FRO ...
- 1018Mysql分表分库
单库单表 单库单表是最常见的数据库设计,例如,有一张用户(user)表放在数据库db中,所有的用户都可以在db库中的user表中查到. 单库多表 随着用户数量的增加,user表的数据量会越来越大,当数 ...