【POJ2699】The Maximum Number of Strong Kings(二分,最大流)

题意:

有n个队伍,两两都有比赛

知道最后每支队伍获胜的场数

求最多有多少队伍,他们战胜了所有获胜场数比自己多的队伍,这些队伍被称为SK

N<=50

思路:把每个队伍和它们两两之间的比赛都当做点,判断最大流是否满流即可

S——>队伍 a[i]

队伍 ——>比赛 1

比赛——>T 1

i号队伍是SK:如果j为SK且a[i]>a[j]则j必胜,如果a[i]<a[j]则i必胜 只要必胜者向他们之间的比赛连1条边即可

如果j不为SK,胜负未知,两个点都向他们之间的比赛连1条边

i号队伍不是SK:对于所有的队伍都胜负未知,同上处理

最暴力的思想就是枚举每个队伍作为SK的可能性再根据得分情况连边,其实也能过

不过可以证明一定存在一种方案,使得SK是排序后得分最多的那些队伍

二分或枚举答案即可

证明见http://blog.csdn.net/sdj222555/article/details/7797257

  1 var head,a:array[1..300]of longint;
  2     fan:array[1..200000]of longint;
  3     vet,next,len,dis,gap,flag:array[0..20000]of longint;
  4     num:array[1..100,1..100]of longint;
  5     n,i,j,tot,l,r,mid,last,s,source,src,cas,v,k:longint;
  6     ch:ansistring;
  7
  8 function min(x,y:longint):longint;
  9 begin
 10  if x<y then exit(x);
 11  exit(y);
 12 end;
 13
 14 procedure add(a,b,c:longint);
 15 begin
 16
 17  inc(tot);
 18  next[tot]:=head[a];
 19  vet[tot]:=b;
 20  len[tot]:=c;
 21  head[a]:=tot;
 22
 23  inc(tot);
 24  next[tot]:=head[b];
 25  vet[tot]:=a;
 26  len[tot]:=0;
 27  head[b]:=tot;
 28
 29 end;
 30
 31 procedure swap(var x,y:longint);
 32 var t:longint;
 33 begin
 34  t:=x; x:=y; y:=t;
 35 end;
 36
 37 procedure qsort(l,r:longint);
 38 var i,j,mid:longint;
 39 begin
 40  i:=l; j:=r; mid:=a[(l+r)>>1];
 41  repeat
 42   while mid<a[i] do inc(i);
 43   while mid>a[j] do dec(j);
 44   if i<=j then
 45   begin
 46    swap(a[i],a[j]);
 47    inc(i); dec(j);
 48   end;
 49  until i>j;
 50  if l<j then qsort(l,j);
 51  if i<r then qsort(i,r);
 52 end;
 53
 54 function dfs(u,aug:longint):longint;
 55 var e,v,t,val,flow:longint;
 56 begin
 57  if u=src then exit(aug);
 58  e:=head[u]; val:=s-1; flow:=0;
 59  while e<>0 do
 60  begin
 61   v:=vet[e];
 62   if len[e]>0 then
 63   begin
 64    if dis[u]=dis[v]+1 then
 65    begin
 66     t:=dfs(v,min(len[e],aug-flow));
 67     len[e]:=len[e]-t;
 68     len[fan[e]]:=len[fan[e]]+t;
 69     flow:=flow+t;
 70     if dis[source]>=s then exit(flow);
 71     if aug=flow then break;
 72    end;
 73    val:=min(val,dis[v]);
 74   end;
 75   e:=next[e];
 76  end;
 77  if flow=0 then
 78  begin
 79   dec(gap[dis[u]]);
 80   if gap[dis[u]]=0 then dis[source]:=s;
 81   dis[u]:=val+1;
 82   inc(gap[dis[u]]);
 83  end;
 84  exit(flow);
 85 end;
 86
 87 function maxflow:longint;
 88 var ans:longint;
 89 begin
 90  fillchar(gap,sizeof(gap),0);
 91  fillchar(dis,sizeof(dis),0);
 92  gap[0]:=s; ans:=0;
 93  while dis[source]<s do ans:=ans+dfs(source,maxlongint);
 94  exit(ans);
 95 end;
 96
 97 procedure build(k:longint);
 98 var i,j:longint;
 99 begin
100  fillchar(flag,sizeof(flag),0);
101  fillchar(head,sizeof(head),0); tot:=0;
102
103  for i:=1 to k do
104  begin
105   for j:=1 to i-1 do
106   begin
107    flag[num[i,j]]:=1;
108    add(i,num[i,j],1);
109   end;
110   for j:=i+1 to n do
111    if (a[j]<a[i])and(j<=k)and(flag[num[i,j]]=0) then
112    begin
113     flag[num[i,j]]:=1;
114     add(j,num[i,j],1);
115    end
116     else if flag[num[i,j]]=0 then
117     begin
118      flag[num[i,j]]:=1;
119      add(i,num[i,j],1);
120      add(j,num[i,j],1);
121     end;
122  end;
123  for i:=k+1 to n do
124   for j:=1 to n do
125    if (i<>j)and(flag[num[i,j]]=0) then
126    begin
127     add(i,num[i,j],1);
128     add(j,num[i,j],1);
129     flag[num[i,j]]:=1;
130    end;
131  for i:=1 to n do add(source,i,a[i]);
132  for i:=1 to n do
133   for j:=1 to n do
134    if i<j then add(num[i,j],src,1);
135 end;
136
137 function isok(k:longint):boolean;
138 begin
139  if maxflow=n*(n-1) div 2 then exit(true);
140  exit(false);
141 end;
142
143 begin
144  assign(input,‘poj2699.in‘); reset(input);
145  assign(output,‘poj2699.out‘); rewrite(output);
146  for i:=1 to 200000 do
147   if i mod 2=1 then fan[i]:=i+1
148    else fan[i]:=i-1;
149  readln(cas);
150  for v:=1 to cas do
151  begin
152   fillchar(num,sizeof(num),0);
153   readln(ch); k:=length(ch);
154   fillchar(a,sizeof(a),0); n:=0;
155   i:=0;
156   while i<k do
157   begin
158    inc(i);
159    while (i<k)and(ch[i]=‘ ‘) do inc(i);
160    inc(n);
161    while (i<=k)and(ch[i]<>‘ ‘) do
162    begin
163     a[n]:=a[n]*10+ord(ch[i])-ord(‘0‘);
164     inc(i);
165    end;
166   end;
167
168   qsort(1,n); s:=n;
169   for i:=1 to n do
170    for j:=1 to n do
171     if i<>j then
172     begin
173      if num[j,i]=0 then
174      begin
175       inc(s); num[i,j]:=s;
176      end
177       else num[i,j]:=num[j,i];
178     end;
179   inc(s); source:=s; inc(s); src:=s;
180
181   l:=0; r:=n; last:=0;
182   while l<=r do
183   begin
184    mid:=(l+r)>>1;
185    build(mid);
186    if isok(mid) then begin last:=mid; l:=mid+1; end
187     else r:=mid-1;
188   end;
189   writeln(last);
190  end;
191  close(input);
192  close(output);
193 end.
时间: 2024-10-10 17:49:25

【POJ2699】The Maximum Number of Strong Kings(二分,最大流)的相关文章

解题报告 之 POJ2699 The Maximum Number of Strong Kings

解题报告 之 POJ2699 The Maximum Number of Strong Kings 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 t

POJ2699 The Maximum Number of Strong Kings

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

POJ 2699 The Maximum Number of Strong Kings (最大流+枚举)

http://poj.org/problem?id=2699 题意: 一场联赛可以表示成一个完全图,点表示参赛选手,任意两点u, v之间有且仅有一条有向边(u, v)或( v, u),表示u打败v或v打败u.一个选手的得分等于被他打败的选手总数.一个选手被称为“strong king”当且仅当他打败了所有比他分高的选手.分数最高的选手也是strong king.现在给出某场联赛所有选手的得分序列,由低到高,问合理安排每场比赛的结果后最多能有几个strong king.已知选手总数不超过10个.

POJ 2699 The Maximum Number of Strong Kings 竞赛图+最大流

题目大意:有n个人之间互相竞赛,现在给出每个人赢了多少局.若定义一个人是最高分或者这个人赢了所有比他分高的人,那么这个人就算赢了.问最多可能有多少人赢. 思路:最大流模型的另一种应用.二分图,左边是所有选手,右边是所有比赛. S->所有选手 f:该选手赢了多少局 所有比赛->T f:1 由于最多只有十个人,所以枚举答案就行了.枚举最多有多少人赢了,如果一个分比较低的人赢了,那么分比他高的人必定也可以赢,所以就假设是分数最高的n个人赢了. 在这些人之间的竞赛需要保证分低的人赢了分高的人,那么 i

【POJ2699】The Maximum Number of Strong Kings

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 playe

POJ2699_The Maximum Number of Strong Kings

这题目,,,真是...诶.坑了好久. 给一个有向图.U->V表示U可以打败V并得一分. 如果一个人的得分最高,或者他打败所有比自己得分高的人,那么此人就是king. 现在给出每个人的得分,求最多可能有多少个king同时存在. 可以证明,如果有k个人是king,那么至少有一种分配方案使得这k个king都是分数最高的那k个人.(证明略,想想就知道了) 于是我们可以开始枚举从i个人开始,后面的都是king. 除了源点和汇点以外,还有两种点,一种表示人(n),一种表示比赛(n*(n/2)/2). 如果一

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 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, th

【POJ2699】The Maximum Number of Strong Kings 枚举(二分)+网络流check、

题意: 有n个人,两两都有比赛,然后有每个人的胜场次数. 规定把比自己胜场次数多的人都赢了的就是strong(weak) king (vegetables) (why i say that they are so weak? :****,how do you think a person who beat the heroes but defeated at the dogface? ) 让你安排比赛,问最多有多少个strongking? 题解: 首先(有人说)能证如果有k个sk,那么一定可以是

【poj2699】 The Maximum Number of Strong Kings

http://poj.org/problem?id=2699 (题目链接) 题意 给出1张有向完全图.U->V表示U可以打败V并得一分.如果一个人的得分最高,或者他打败所有比自己得分高的人,那么此人就是king.现在按顺序给出每个人的得分,求最多可能有多少个king同时存在. Solution 想了半天贪心,然而得分相等的情况真的很不好处理..真的没想到是最大流..左转题解:http://blog.csdn.net/sdj222555/article/details/7797257 考虑这样建图