POJ2699 The Maximum Number of Strong Kings
2024-10-17 23:24:37
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 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.
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
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 ;
}
最新文章
- java性能调优及问题追踪--Btrace的使用
- oracle 读书笔记
- 3D开发的基本知识
- OpenCV之响应鼠标(一):利用鼠标获取坐标
- JDBC-ODBC桥乱码问题解决方案
- 14、AppWidget及Launcher
- size_t和size_type类型
- http常见的get请求方式和set请求方式。
- proc中tran的一般处理
- Linux(5)压缩和归档管理
- JavaNIO深入学习
- C#异常处理--C#基础
- SpriteKit给游戏弹跳角色添加一个高度标示器
- CSS_圣杯布局和双飞翼布局
- Vue表单修饰符(lazy,number,trim)
- elasticsearch index tuning
- 《DSP using MATLAB》Problem 6.4
- C高级第三次作业(1)
- Android Layout: TableLayout
- WebService 闲聊