题目大意:有n个人,两两之间进行比赛,一个如果击败了所有分数比他高的人或者自己本身就是分数最高的人,那么他就是sp,给出所有人的得分情况,问最多有多少个sp;
题目解析:构图,源->人->比赛->汇,源到人的容量就是每个人的得分情况,比赛到汇容量就是1;看到n最多就是10,我们可以枚举sp的个数为x,那么分数高的前x名就是sp,那么枚举人到比赛的时候,如果那个人是后x名,并且它的对手分数高于他,那么就从他连向比赛,对手不连,其余情况两个人都要连比赛;
AC代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
using namespace std;
const int inf=0x3fffffff;
const int maxn=1000;
struct node
{
int to,cap,rev;
node(int a,int b,int c)
{
to=a;
cap=b;
rev=c;
}
};
struct edge
{
int to,cap;
edge(int a,int b)
{
to=a;
cap=b;
}
};
vector<node>vec[maxn];
vector<edge>tor[maxn];
int pre[maxn],iter[maxn],graph[301][301],n;
bool vis[maxn];
bool used[301][301];
void add_edge(int from,int to,int cost)
{
vec[from].push_back(node(to,cost,vec[to].size()));
vec[to].push_back(node(from,cost,vec[from].size()-1));
}
void bfs(int s){
memset(pre,-1,sizeof(pre));
queue<int>que;
pre[s]=0;que.push(s);
while(!que.empty()){
int v=que.front();que.pop();
for(int i=0;i<vec[v].size();i++){
node &e=vec[v][i];
if(e.cap>0&&pre[e.to]<0){
pre[e.to]=pre[v]+1;
que.push(e.to);
}
}
}
}
int dfs(int v,int t,int f){
if(v==t) return f;
for(int &i=iter[v];i<vec[v].size();i++){
node &e=vec[v][i];
if(e.cap>0&&pre[v]<pre[e.to]){
int d=dfs(e.to,t,min(f,e.cap));
if(d>0){
e.cap-=d;
vec[e.to][e.rev].cap+=d;
return d;
}
}
}
return 0;
}
int max_flow(int u,int v)
{
int flow=0;
while(1)
{
bfs(u);
if(pre[v]<0) return flow;
memset(iter,0,sizeof(iter));
int f;
while((f=dfs(u,v,inf))>0) flow+=f;
}
}
int score[110],cpt[12][12],cnt;
void build(int s,int t,int num)
{
int i,j;
for(i=0;i<maxn;i++) vec[i].clear();
for(i=1;i<=n;i++)
add_edge(s,i,score[i]);
for(i=n+1;i<=cnt+n;i++)
add_edge(i,t,1);
for(i=1;i<=n;i++)
{
for(j=i+1;j<=n;j++)
{
if(score[i]<score[j]&&i>=n-num+1)
add_edge(i,cpt[i][j]+n,1);
else
{
add_edge(i,cpt[i][j]+n,1);
add_edge(j,cpt[i][j]+n,1);
}
}
}
}
int main()
{
int t,i,j;
scanf("%d",&t);
getchar();
while(t--)
{
char s[30];
n=0,cnt=0;
gets(s);
int x=0,l=strlen(s);;
for(i=0;i<l;i++)
{
if (s[i]>='0' && s[i]<='9'){
x=x*10+s[i]-'0';
if (i==l-1 || s[i+1]==' ') score[++n]=x,x=0;
}
}
for(i=1;i<=n;i++)
{
for(j=i+1;j<=n;j++)
{
cpt[i][j]=++cnt;
}
}
for(i=n;i>=1;i--)
{
build(0,n+cnt+1,i);
if(max_flow(0,n+cnt+1)==cnt)
{
printf("%d\n",i);
break;
}
}
}
return 0;
}