poj2699

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
}
View Code

以上是关于poj2699的主要内容,如果未能解决你的问题,请参考以下文章

poj2699 转化为可行性判定问题+二分枚举+最大流

poj2699 The Maximum Number of Strong Kings

POJ2699 The Maximum Number of Strong Kings

POJ 2699 The Maximum Number of Strong Kings Description

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

POJ2699The Maximum Number of Strong Kings(二分,最大流)