This question... Ah. It has been a long time.
Returns a directed graph. U-> V indicates that u can beat V with a single point.
If a person scored the most, or beat anyone who scored higher than himself, then this person is king.
Now we can give a score for each person and find the maximum number of King instances that may exist at the same time.
It can be proved that if k people are king, there is at least one allocation scheme so that K King people are the k people with the highest scores. (Prove it a little, just think about it)
So we can start to enumerate from I, followed by King.
In addition to the Source and Sink points, there are two types of points, one is the person (n), and the other is the game (N * (N/2)/2 ).
If a person can score from a game, then the person connects to the game with a side with 1 traffic.
For the k-th individual currently enumerated, neither of the previous ones is king, so both of them can be connected to the match related to this individual. For persons later than K, to compete with a person with a large number, only K can win, so the network flow model will come out.
We can enumerate the location of the first king from small to large. After creating a graph, we can determine whether the stream is full.
This is a good question, just .... This input is not flattering. Various spaces are messy and strange input formats. At first, the number of input persons n will die? There is also a pitfall prompt. If a few people share the same score, even if they are behind the enumeration position, they can also lose to the same person with their scores, with special attention.
Summon code:
#include <iostream>#include <cstring>#include <cstdio>#define maxn 2550#define maxm 555500using namespace std;const int inf=~0U>>2;int next[maxm],to[maxm],c[maxm],first[maxn],edge;int d[maxn],tag[maxn],f[maxn][maxn],TAG=520;int Q[maxm],bot,top;bool can[maxn];int a[maxn],n,m,sum,ans,s,t,T,maxscore;char S[maxm];void _input(){ gets(S); n=0,m=0,maxscore=0; int L=strlen(S); for (int i=0; i<L; i++) { if (S[i]>=‘0‘ && S[i]<=‘9‘) { m=m*10+S[i]-‘0‘; if (i==L-1 || S[i+1]<‘0‘ || S[i+1]>‘9‘) a[++n]=m,m=0,maxscore=max(maxscore,a[n]); } } for (int i=1; i<n; i++) for (int j=i+1; j<=n; j++) f[i][j]=f[j][i]=++m; //cout<<n<<‘ ‘<<m<<endl; s=0,t=n+m+1,sum=m;}void addedge(int U,int V,int W){ //cout<<" A edge : "<<U<<" -> "<<V<<" :: "<<W<<endl; edge++; to[edge]=V,c[edge]=W,next[edge]=first[U],first[U]=edge; edge++; to[edge]=U,c[edge]=0,next[edge]=first[V],first[V]=edge;}bool bfs(){ Q[bot=top=1]=t,d[t]=0,tag[t]=++TAG,can[t]=false; while (bot<=top) { int cur=Q[bot++]; for (int i=first[cur]; i!=-1; i=next[i]) if (c[i^1]>0 && tag[to[i]]!=TAG) { tag[to[i]]=TAG; d[to[i]]=d[cur]+1; can[to[i]]=false; Q[++top]=to[i]; if (to[i]==s) return true; } } return false;}int dfs(int cur,int num){ if (cur==t) return num; int tmp=num,k; for (int i=first[cur]; i!=-1; i=next[i]) if (c[i]>0 && tag[to[i]]==TAG && d[to[i]]==d[cur]-1 && !can[to[i]]) { k=dfs(to[i],min(c[i],num)); if (k) num-=k,c[i]-=k,c[i^1]+=k; if (num==0) break; } if (num) can[cur]=true; return tmp-num;}bool check(int x){ edge=-1; for (int i=s; i<=t; i++) first[i]=-1; for (int i=1; i<=n; i++) addedge(s,i,a[i]); for (int i=1; i<x; i++) for (int j=i+1; j<=n; j++) addedge(i,f[i][j]+n,1),addedge(j,f[i][j]+n,1); for (int i=x; i<n; i++) for (int j=i+1; j<=n; j++) { addedge(i,f[i][j]+n,1); if (a[i]==maxscore) addedge(j,f[i][j]+n,1); } for (int i=n+1; i<=n+sum; i++) addedge(i,t,1); for (ans=0; bfs(); ) ans+=dfs(s,inf); return ans>=sum;}int main(){ scanf("%d",&T); getchar(); while (T--) { _input(); for (int i=1; i<=n; i++) if (check(i)) { printf("%d\n",n-i+1); break; } } return 0;}