【POJ】【2699】The Maximum Number of Strong Kings

网络流/最大流/二分or贪心



  题目大意:有n个队伍,两两之间有一场比赛,胜者得分+1,负者得分+0,问最多有几只队伍打败了所有得分比他高的队伍?

  可以想到如果存在这样的“strong king”那么一定是胜场较多的队伍……(比他赢得多的队伍num少,而他总共赢得场数times足够多,至少得满足times>=num吧?)

  那么我们可以二分/枚举k,表示胜场前k多的队伍是stong king。(这题范围小,只有10支队伍,如果队伍较多我们就需要二分了……)

  最最丧心病狂的是!!!出题人TMD卡读入!!!居然在数字与数字之间会有多个空格!!!像我这样直接遇到空格就a[++n]=v,v=0;的就挂了!!!

  妈蛋害我调了一晚上!

  1 Source Code
  2 Problem: 2699        User: sdfzyhy
  3 Memory: 716K        Time: 0MS
  4 Language: G++        Result: Accepted
  5
  6     Source Code
  7
  8     //POJ 2699
  9     #include<vector>
 10     #include<cstdio>
 11     #include<sstream>
 12     #include<cstring>
 13     #include<cstdlib>
 14     #include<iostream>
 15     #include<algorithm>
 16     #define rep(i,n) for(int i=0;i<n;++i)
 17     #define F(i,j,n) for(int i=j;i<=n;++i)
 18     #define D(i,j,n) for(int i=j;i>=n;--i)
 19     #define pb push_back
 20     using namespace std;
 21     inline int getint(){
 22         int v=0,sign=1; char ch=getchar();
 23         while(ch<‘0‘||ch>‘9‘){ if (ch==‘-‘) sign=-1; ch=getchar();}
 24         while(ch>=‘0‘&&ch<=‘9‘){ v=v*10+ch-‘0‘; ch=getchar();}
 25         return v*sign;
 26     }
 27     const int N=100,M=1000,INF=~0u>>2;
 28     typedef long long LL;
 29     /******************tamplate*********************/
 30     int n,m,tot,ans,num,a[N];
 31     char s1[N];
 32     struct edge{int to,v;};
 33     struct Net{
 34         edge E[M];
 35         int head[N],next[M],cnt;
 36         void ins(int x,int y,int v){
 37             E[++cnt]=(edge){y,v};
 38             next[cnt]=head[x]; head[x]=cnt;
 39         }
 40         void add(int x,int y,int v){
 41             ins(x,y,v); ins(y,x,0);
 42         }
 43         int s,t,d[N],Q[M];
 44         bool mklevel(){
 45             F(i,0,t) d[i]=-1;
 46             d[s]=0;
 47             int l=0,r=-1;
 48             Q[++r]=s;
 49             while(l<=r){
 50                 int x=Q[l++];
 51                 for(int i=head[x];i;i=next[i])
 52                     if (d[E[i].to]==-1 && E[i].v){
 53                         d[E[i].to]=d[x]+1;
 54                         Q[++r]=E[i].to;
 55                     }
 56             }
 57             return d[t]!=-1;
 58         }
 59         int dfs(int x,int a){
 60             if (x==t) return a;
 61             int flow=0;
 62             for(int i=head[x];i && flow<a;i=next[i])
 63                 if (E[i].v && d[E[i].to]==d[x]+1){
 64                     int f=dfs(E[i].to,min(a-flow,E[i].v));
 65                     E[i].v-=f;
 66                     E[i^1].v+=f;
 67                     flow+=f;
 68                 }
 69             if (!flow) d[x]=-1;
 70             return flow;
 71         }
 72         void Dinic(){
 73             while(mklevel()) ans+=dfs(s,INF);
 74         }
 75         void init(){
 76             n=0;
 77             gets(s1);
 78             int v=0;
 79             stringstream ss(s1);
 80             while(ss >> v) a[++n]=v;
 81         }
 82         bool check(int k){
 83             cnt=1; F(i,s,t) head[i]=0;
 84             F(i,1,n) add(s,i,a[i]);
 85             int l=n;
 86             F(i,1,n) F(j,i+1,n){
 87                 add(++l,t,1);
 88                 if(i>=k && a[j]>a[i]) add(i,l,1);
 89                 else add(i,l,1),add(j,l,1);
 90             }
 91             ans=0;
 92             Dinic();
 93             return ans==m;
 94         }
 95         void solve(){
 96             m=n*(n-1)/2;
 97             s=0; t=n+m+1;
 98             int l=0,r=n,mid,as=0;
 99     /*
100             while(l<=r){
101                 mid=l+r>>1;
102     //            printf("l=%d r=%d mid=%d\n",l,r,mid);
103                 if (check(mid)) as=mid,r=mid-1;
104                 else l=mid+1;
105             }
106     二分        */
107     //        D(i,n,1) if(!check(i)){as=i;break;}
108
109             F(i,1,n) if(check(i)){as=i-1;break;}
110             printf("%d\n",n-as);
111         }
112     }G1;
113
114     int main(){
115     #ifndef ONLINE_JUDGE
116         freopen("2699.in","r",stdin);
117         freopen("2699.out","w",stdout);
118     #endif
119         int T=getint();
120         while(T--){
121             G1.init();G1.solve();
122         }
123         return 0;
124     }

时间: 2024-12-15 00:01:47

【POJ】【2699】The Maximum Number of Strong Kings的相关文章

【POJ2699】The Maximum Number of Strong Kings

Description A tournament can be represented by a complete graph in which each vertex denotes a player and a directed edge is from vertex x to vertex y if player x beats player y. For a player x in a tournament T, the score of x is the number of playe

POJ 2699 The Maximum Number of Strong Kings Description

The Maximum Number of Strong Kings Description A tournament can be represented by a complete graph in which each vertex denotes a player and a directed edge is from vertex x to vertex y if player x beats player y. For a player x in a tournament T, th

POJ2699 The Maximum Number of Strong Kings

Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2102   Accepted: 975 Description A tournament can be represented by a complete graph in which each vertex denotes a player and a directed edge is from vertex x to vertex y if player x beats

POJ2699_The Maximum Number of Strong Kings

这题目,,,真是...诶.坑了好久. 给一个有向图.U->V表示U可以打败V并得一分. 如果一个人的得分最高,或者他打败所有比自己得分高的人,那么此人就是king. 现在给出每个人的得分,求最多可能有多少个king同时存在. 可以证明,如果有k个人是king,那么至少有一种分配方案使得这k个king都是分数最高的那k个人.(证明略,想想就知道了) 于是我们可以开始枚举从i个人开始,后面的都是king. 除了源点和汇点以外,还有两种点,一种表示人(n),一种表示比赛(n*(n/2)/2). 如果一

解题报告 之 POJ2699 The Maximum Number of Strong Kings

解题报告 之 POJ2699 The Maximum Number of Strong Kings Description A tournament can be represented by a complete graph in which each vertex denotes a player and a directed edge is from vertex x to vertex y if player x beats player y. For a player x in a t

【poj2699】 The Maximum Number of Strong Kings

http://poj.org/problem?id=2699 (题目链接) 题意 给出1张有向完全图.U->V表示U可以打败V并得一分.如果一个人的得分最高,或者他打败所有比自己得分高的人,那么此人就是king.现在按顺序给出每个人的得分,求最多可能有多少个king同时存在. Solution 想了半天贪心,然而得分相等的情况真的很不好处理..真的没想到是最大流..左转题解:http://blog.csdn.net/sdj222555/article/details/7797257 考虑这样建图

【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条边

【POJ2699】The Maximum Number of Strong Kings 枚举(二分)+网络流check、

题意: 有n个人,两两都有比赛,然后有每个人的胜场次数. 规定把比自己胜场次数多的人都赢了的就是strong(weak) king (vegetables) (why i say that they are so weak? :****,how do you think a person who beat the heroes but defeated at the dogface? ) 让你安排比赛,问最多有多少个strongking? 题解: 首先(有人说)能证如果有k个sk,那么一定可以是

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

http://poj.org/problem?id=2699 题意: 一场联赛可以表示成一个完全图,点表示参赛选手,任意两点u, v之间有且仅有一条有向边(u, v)或( v, u),表示u打败v或v打败u.一个选手的得分等于被他打败的选手总数.一个选手被称为“strong king”当且仅当他打败了所有比他分高的选手.分数最高的选手也是strong king.现在给出某场联赛所有选手的得分序列,由低到高,问合理安排每场比赛的结果后最多能有几个strong king.已知选手总数不超过10个.