POJ2699The Maximum Number of Strong Kings(二分,最大流)

Posted myx12345

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ2699The 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.

 

以上是关于POJ2699The Maximum Number of Strong Kings(二分,最大流)的主要内容,如果未能解决你的问题,请参考以下文章

POJ 2699 The Maximum Number of Strong Kings Description

poj2699 The Maximum Number of Strong Kings

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

POJ2699The Maximum Number of Strong Kings(二分,最大流)

bzoj4604The kth maximum number

[bzoj4604] The kth maximum number