题意:n个人比赛,得分最高的算赢了,打败了所有比自己高的分的人也算赢了,问最多有多少人赢了。。
网络流:人数很少。把每一场比赛都看作一个点。建建图;枚举答案就行了。
恶心的输入啊。。输入的每一行后面还可能有空格。再codeblocks中直接把后面的空格去掉了。。tle,wa了n多次。。。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
using namespace std;
const int N = 99;
const int INF = 0x3f3f3f3f;
int g[N][N],gap[N],dist[N],pre[N],cur[N];
int sap(int s1,int t1,int n)
{
int ret = 0,aug = INF,u,v;
memset(gap,0,sizeof(gap));
memset(dist,0,sizeof(dist));
for(int i=0;i<=n;i++) cur[i] = 1;
u = pre[s1] = s1;
gap[0] = n;
while(dist[s1]<=n){
loop:
for(v = cur[u];v<=n;v++)
if(g[u][v]>0&&dist[u] ==dist[v]+1)
{
cur[u] = v;aug = min(aug,g[u][v]);
pre[v] = u;
u = v;
if(u==t1){
ret+=aug;
for(u=pre[u];v!=s1;v=u,u=pre[u])
g[u][v]-=aug,g[v][u]+=aug;
aug = INF;
}
goto loop;
}
int mind =n;
for(v=1;v<=n;v++)
if(g[u][v]>0&&mind>dist[v])
mind = dist[v],cur[u] = v;
if(--gap[dist[u]]<=0) break;
gap[dist[u]=mind+1]++;
u=pre[u];
}return ret;
}
int re[19];
int n;
void init()
{
char a[10000];
n = 1;
gets(a);
int len=strlen(a),tmp=0,f = 0;
for(int i=0;i<=len;i++)
{
if(a[i]<'0'||a[i]>'9')
{
if(f)
{
re[n++] = tmp;
tmp = 0;f = 0;
}
}else
{
tmp = tmp*10+a[i]-'0'; f = 1;
}
}
}
int solve()
{
int ans=n-1 ;
re[0] = -1;
sort(re+1,re+n+1);
//for(ans = n-1;re[ans]==re[ans+1];ans--);
while(ans>=0)
{
memset(g,0,sizeof(g));
int s = n+1,t = n+2;
for(int i=1;i<=n;i++) g[s][i] = re[i];
int tmp = t;
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
tmp++;
g[tmp][t] = 1;
if(i>ans&&re[j]!=re[i])
g[i][tmp] =1;
else
g[i][tmp] = g[j][tmp] = 1;
}
}
if(sap(s,t,tmp)<(n*(n-1)/2))
{
return n-ans-1;
}ans--;
}
return n;
}
int main()
{
freopen("in.txt","r",stdin);
int cas;
scanf("%d",&cas); getchar();
while(cas--)
{
init();n--;
// for(int i=1;i<=n;i++) cout<<re[i]<<" ";cout<<endl;
printf("%d\n",solve());
}
return 0;
}