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 3Sample Output
2
4
5
3
5
【分析】
主要是有一個貪心的思想,就是如果有一種情況使其中k個人是能力者的話,那麼總有一種情況使分數最高的k個人是能力者。(因為交換一下勝利的場就可以了)。所以可以列舉有k個人是能力者,規定後k個人就是能力者,建立約束圖,跑最大流判滿流即可。
如下圖(證明上面那一個貪心):
假設有一種情況使得有k個能力者,但不是後k個,證明有一種情況是後k個都是能力者。
上圖,假設C是能力者但不是後k個,E不是能力者但是後k個。
因為C是能力者E不是,則在E的後面必有一個G(隨便是什麼),C贏了它,E沒有贏他。
因為E的分數大於C,則在C之前必有一個A(隨便是什麼),C沒有贏他,E贏了他。
那麼我們交換一下勝負場,C、E分數都不變,然後E離能力者更近一步。
繼續交換下去,後k個一定能成為能力者。
證畢。
於是建個圖跑最大流。
差不多這樣建圖:
程式碼如下:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define Maxn 1100
#define Maxm 100100
#define INF 0xfffffff char s[];
int a[Maxn],al,lg[Maxn];
int dis[Maxn],first[Maxn]; struct node
{
int x,y,f,o,next;
}t[Maxm];int len; int st,ed,sum,h=; int mymin(int x,int y) {return x<y?x:y;} void ins(int x,int y,int f)
{
if(f==) return;
if(y==ed) sum+=f;
t[++len].x=x;t[len].y=y;t[len].f=f;
t[len].next=first[x];first[x]=len;t[len].o=len+;
t[++len].x=y;t[len].y=x;t[len].f=;
t[len].next=first[y];first[y]=len;t[len].o=len-;
} queue<int > q;
bool bfs()
{
while(!q.empty()) q.pop();
memset(dis,-,sizeof(dis));
q.push(st);dis[st]=;
while(!q.empty())
{
int x=q.front();q.pop();
for(int i=first[x];i;i=t[i].next) if(t[i].f>)
{
int y=t[i].y;
if(dis[y]==-)
{
dis[y]=dis[x]+;
q.push(y);
}
}
}
if(dis[ed]==-) return ;
return ;
} int ffind(int x,int flow)
{
if(x==ed) return flow;
int now=;
for(int i=first[x];i;i=t[i].next) if(t[i].f>)
{
int y=t[i].y;
if(dis[y]==dis[x]+)
{
int a=ffind(y,mymin(flow-now,t[i].f));
t[i].f-=a;
t[t[i].o].f+=a;
now+=a;
}
if(now==flow) break;
}
if(now==) dis[x]=-;
return now;
} bool max_flow()
{
int ans=;
while(bfs())
{
ans+=ffind(st,INF);
}
if(ans==sum) return ;
return ;
} bool check(int x)
{
len=;sum=;h=ed;
memset(first,,sizeof(first));
for(int i=al-x+;i<=al;i++)
{
if(a[i]<lg[i]) return ;
ins(i,ed,a[i]-lg[i]);
for(int j=i+;j<=al-lg[i];j++)
{
ins(st,++h,);
ins(h,i,);
ins(h,j,);
}
}
for(int i=;i<=al-x;i++) ins(i,ed,a[i]);
for(int i=;i<=al-x;i++)
for(int j=i+;j<=al;j++)
{
ins(st,++h,);
ins(h,i,);
ins(h,j,);
} if(max_flow()) return ; return ;
} int main()
{
int T;
scanf("%d",&T);getchar();
while(T--)
{
gets(s);
int l=strlen(s);
int now=;al=;
for(int i=;i<l;i++)
{
if((s[i]<=''||s[i]>='')&&(i>=&&s[i-]>=''&&s[i-]<=''))
{
a[++al]=now;
now=;
}
else if(s[i]>=''&&s[i]<='')now=now*+s[i]-'';
}
if(s[l-]>=''&&s[l-]<='') a[++al]=now;
for(int i=;i<=al;i++)
{
lg[i]=;
for(int j=i+;j<=al;j++) if(a[j]>a[i]) lg[i]++;
}
st=al+;ed=st+;h=ed;
int ans=;
for(int i=al;i>=;i--)
{
if(check(i)) {ans=i;break;}
}
printf("%d\n",ans);
}
return ;
}
[POJ2699]
2016-06-05 10:17:08