zoukankan      html  css  js  c++  java
  • 【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.
  • 相关阅读:
    Oracle之PL/SQL学习笔记
    Git常用命令
    Web前端上万字的知识总结
    Objective-C中小怪兽的逻辑
    PHP精选数组函数
    数据库连接字符串方法
    WM_CAP_DRIVER_CONNECT
    GB2312/ANSI编码转中文字符
    opencv播放不了AVI视频的问题
    我的MFC/C++学习笔记 http://blog.bccn.net/CrystalFan/6909
  • 原文地址:https://www.cnblogs.com/myx12345/p/6230568.html
Copyright © 2011-2022 走看看