poj2699

神题目=神题解+神读入

  题意:n个人比赛, 两两比,共n*(n-1), 赢得1分, n<=10(这给了我们枚举的暗示),如果一个人打败了所有比自己分数高的人, 或者他本身就是分数最高的, 那么他就是StrongKing。可能有多个Strong King, 现在按非降的顺序给你每个人的得分(不难道想到容量把), 问Strong King最多能有几个

  题解:二分图,左边是人,右边是比赛,源点到人连容量为score[i]的边,汇点到比赛连容量为1的边。然后枚举答案ans,由于分数越高的人成为strongking的可能性较大(我一开始没有意识到这点,还想用2^10的枚举),于是让后ans个人成为strongking,然后对这ans个人中的i,j,如果score[i]<score[j]则i向match[i][j]连容量为1的边。然后对剩余的比赛match[i][j],让i,j分别向点match[i][j]连容量为1的边。当maxflow==n*(n-1)/2时,则ans为解

贴代码(看读入...):

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<queue>
using namespace std;
const int maxn=1000,maxm=11000,inf=0x7fffffff;
int n,m,a,b,c,s,t,tot=1,maxflow,k[maxn],head[maxn],cur[maxn],h[maxn];
queue<int> q;
char ss[maxn];
struct node{
    int go,next,v;
}e[maxm];
inline int read(){
    int x=0,f=1;char ch=getchar();
    while (ch>‘9‘ || ch<‘0‘){if (ch==‘\n‘) return -323;ch=getchar();}
    while (ch>=‘0‘ && ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
inline void addedge(int x,int y,int v){
    e[++tot]=(node){y,head[x],v};head[x]=tot;
    e[++tot]=(node){x,head[y],0};head[y]=tot;
}
bool bfs(){
    for (int i=1;i<=t;i++) h[i]=-1;
    q.push(s);h[s]=0;
    while (!q.empty()){
        int x=q.front();q.pop();
        for (int i=head[x];i;i=e[i].next){
            if (e[i].v&&h[e[i].go]==-1){
                h[e[i].go]=h[x]+1;
                q.push(e[i].go);
            }
        }
    }
    return h[t]!=-1;
}
int dfs(int x,int f){
    if (x==t) return f;
    int tmp,used=0;
    for (int i=cur[x];i;i=e[i].next){
        if (e[i].v&&h[e[i].go]==h[x]+1){
            tmp=dfs(e[i].go,min(e[i].v,f-used));
            e[i].v-=tmp;if (e[i].v) cur[x]=i;
            e[i^1].v+=tmp;used+=tmp;
            if (used==f) return f;
        }
    }
    if (!used) h[x]=-1;
    return used;
}
void dinic(){
    maxflow=0;
    while (bfs()){
        for (int i=1;i<=t;i++) cur[i]=head[i];
        maxflow+=dfs(s,inf);
    }
}
int main(){
    n=read();
    while (n--){
        m=0;
        //神读入
        gets(ss);
        int x=0,l=strlen(ss);
        for (int i=0;i<l;i++){
            if (ss[i]>=‘0‘ && ss[i]<=‘9‘){
                x=x*10+ss[i]-‘0‘;
                if (i==l-1 || ss[i+1]==‘ ‘) k[++m]=x,x=0;
            }
        }

        s=m+1;t=500;c=m*(m-1)/2;
        for (int i=m;i;i--){
//            cout<<"i:"<<i<<endl;
            tot=1;
            memset(head,0,sizeof(head));
            for (int j=1;j<=m;j++) addedge(s,j,k[j]);
            for (int j=1;j<m;j++)
                for (int w=j+1;w<=m;w++){
                    addedge(j*m+w,t,1);
                    if (j<i || w<i || k[j]==k[w]) addedge(j,j*m+w,1),addedge(w,j*m+w,1);
                }
            for (int j=i;j<m;j++)
                for (int w=j+1;w<=m;w++) if (k[j]<k[w]) addedge(j,j*m+w,1);
            dinic();
//            cout<<maxflow<<endl;
            if (maxflow!=c){
                printf("%d\n",m-i);
                break;
            }
            if (i==1) printf("%d\n",m);
        }
    }
    return 0;
}

时间: 2024-12-17 09:37:25

poj2699的相关文章

【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

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

解题报告 之 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

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 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2302   Accepted: 1056 Description A tournament can be represented by a complete graph in which each vertex denotes a player and a directed edge is from ve

【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】【1637】Sightseeing tour

网络流/最大流 愚人节快乐XD 这题是给一个混合图(既有有向边又有无向边),让你判断是否有欧拉回路…… 我们知道如果一个[连通]图中每个节点都满足[入度=出度]那么就一定有欧拉回路…… 那么每条边都可以贡献一个出度出来,对于一条边u->v: 连S->edge cap=1; 如果是有向边,就连 edge->v cap=1; 否则(无向边)连edge->u cap=1, edge->v cap=1; 然后每个点的总度数我们是知道的……那么它最后的[出度]就等于 总度数/2.(这个

The Maximum Number of Strong Kings

poj2699:http://poj.org/problem?id=2699 题意:n个人,进行n*(n-1)/2场比赛,赢一场则得到一分.如果一个人打败了所有比他分数高的对手,或者他就是分数最高的,那么他就是strong kind.现在给你每个人的得分,问你最多有多少个strong kind. 题解:自己没有思路,看了别人的题解,才勉强理解了.首先,肯定让得分高的成为strong king,因为概率比较大,然后就是怎建图了.假如,我们已经知道了,有m个strong kind,那么这m个人一定是