zoukankan      html  css  js  c++  java
  • 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 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 players beaten by x. The score sequence of T, denoted by S(T) = (s1, s2, . . . , sn), is a non-decreasing list of the scores of all the players in T. It can be proved that S(T) = (s1, s2, . . . , sn) is a score sequence of T if and only if
    for k = 1, 2, . . . , n and equality holds when k = n. A player x in a tournament is a strong king if and only if x beats all of the players whose scores are greater than the score of x. For a score sequence S, we say that a tournament T realizes S if S(T) = S. In particular, T is a heavy tournament realizing S if T has the maximum number of strong kings among all tournaments realizing S. For example, see T2 in Figure 1. Player a is a strong king since the score of player a is the largest score in the tournament. Player b is also a strong king since player b beats player a who is the only player having a score larger than player b. However, players c, d and e are not strong kings since they do not beat all of the players having larger scores.
    The purpose of this problem is to find the maximum number of strong kings in a heavy tournament after a score sequence is given. For example,Figure 1 depicts two possible tournaments on five players with the same score sequence (1, 2, 2, 2, 3). We can see that there are at most two strong kings in any tournament with the score sequence (1, 2, 2, 2, 3) since the player with score 3 can be beaten by only one other player. We can also see that T2 contains two strong kings a and b. Thus, T2 is one of heavy tournaments. However, T1 is not a heavy tournament since there is only one strong king in T1. Therefore, the answer of this example is 2.


    Input

    The first line of the input file contains an integer m, m <= 10, which represents the number of test cases. The following m lines contain m score sequences in which each line contains a score sequence. Note that each score sequence contains at most ten scores.

    Output

    The maximum number of strong kings for each test case line by line.

    Sample Input

    5
    1 2 2 2 3
    1 1 3 4 4 4 4
    3 3 4 4 4 4 5 6 6 6
    0 3 4 4 4 5 5 5 6
    0 3 3 3 3 3

    Sample Output

    2
    4
    5
    3
    5


    神奇的构图
    把每个人和每场比赛看成两种点
    源点向每个人连,cap为其得分
    每场比赛向汇点连,cap为1

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=1808;
    int head[N],tot,S,T;
    int q[N],dis[N],n,sc[12];
    struct node
    {
        int next,v,w;
    } e[N];
    void add(int u,int v,int w)
    {
        e[tot].v=v;
        e[tot].w=w;
        e[tot].next=head[u];
        head[u]=tot++;
    }
    bool bfs()
    {
        memset(dis,-1,sizeof(dis));
        dis[S]=0;
        int l=0,r=0;
        q[r++]=S;
        while(l<r)
        {
            int u=q[l++];
            for(int i=head[u]; ~i; i=e[i].next)
            {
                int v=e[i].v;
                if(dis[v]==-1&&e[i].w>0)
                {
                    q[r++]=v;
                    dis[v]=dis[u]+1;
                    if(v==T) return true;
                }
            }
        }
        return false;
    }
    int dfs(int s,int low)
    {
        if(s==T||!low) return low;
        int ans=low,a;
        for(int i=head[s]; ~i; i=e[i].next)
        {
            if(e[i].w>0&&dis[e[i].v]==dis[s]+1&&(a=dfs(e[i].v,min(e[i].w,ans))))
            {
                e[i].w-=a;
                e[i^1].w+=a;
                ans-=a;
                if(!ans) return low;
            }
        }
        if(low==ans) dis[s]=-1;
        return low-ans;
    }
    bool Ju(int x){
        tot=0;
        memset(head,-1,sizeof(head));
        for(int i=0;i<n;++i) add(S,i+1,sc[i]),add(i+1,S,0);
        for(int i=n+1;i<=(n*n+n)/2;++i) add(i,T,1),add(T,i,0);
        int pos[15][15],tc=n+1;
        for(int i=1;i<=n;++i) for(int j=i+1;j<=n;++j) pos[i][j]=pos[j][i]=tc++;
        for(int i=1;i<x;++i) for(int j=i+1;j<=n;++j) {
            add(i,pos[i][j],1),add(pos[i][j],i,0);
            add(j,pos[i][j],1),add(pos[i][j],j,0);
        }
        for(int i=x;i<=n;++i) for(int j=i+1;j<=n;++j) {
            add(i,pos[i][j],1),add(pos[i][j],i,0);
            if(sc[i-1]==sc[j-1]) add(j,pos[i][j],1),add(pos[i][j],j,0);
        }
        int ans=0;
        while(bfs()) ans+=dfs(S,10086);
        return ans==n*(n-1)/2;
    }
    int main(){
       int Ta;
       for(scanf("%d ",&Ta);Ta--;){
        char str[108];
        gets(str);
        int len=strlen(str);
        n=(len+1)/2;
        if(n==1) {puts("1");continue;}
        S=0,T=(n*n+n)/2+1;
        for(int i=0;i<len;i+=2) sc[i>>1]=str[i]-'0';
        int l=1,r=n,ans=1;
        sort(sc,sc+n);
        while(l<=r){
            int mid=(l+r)>>1;
            if(Ju(mid)) {r=mid-1;ans=n-mid+1;}
            else l=mid+1;
        }
        printf("%d
    ",ans);
       }
    }
  • 相关阅读:
    Linux 系统目录 以及常见命令
    设计模式C++学习笔记之十三(Decorator装饰模式)
    设计模式C++学习笔记之二(Proxy代理模式)
    Linux 文件基本操作
    Linux 文件系统基本结构 以及命令行 管理
    Linux 入门 bash语句 第三课
    JMeter学习参数化User Defined Variables与User Parameters
    JMeter使用中遇到的问题:Jmeter Debug
    JMeter学习(九)FTP测试计划
    JMeter学习(八)JDBC测试计划-连接Oracle
  • 原文地址:https://www.cnblogs.com/mfys/p/7489051.html
Copyright © 2011-2022 走看看