题意:

      有n个人,任意两个人都比一次赛(一共比了n*(n-1)/2场),赢一场得到一分,最后的时候如果得分最高,或者是自己打败了所有比自己得分都高的人就算是King,给你每个人的最后得分,问最多有多少个人是King.

思路:

      一开始上了就贪心了一次,WA了,改了改之后又贪心了一次,还是没过,然后换思路(其实做这个题目是本着最大流来的),然后就去考虑最大流,最大流的话也比较容易理解,关键是枚举的时候有点说道,先说下建图,把每个人看成一个点,然后把每场比赛看成一个点,源点连接所有人,流量为得分,所有比赛连接汇点,流量1,说到这估计大多数都能建图了吧,接着说,然后就是对于那些King的点,如果和他相关的比赛节点中的另一个点比他分高,那么他一定要赢这场比赛,那么他连接这场比赛的点,否则的话就是不确定,谁赢都行,那么和这场比赛相关的两个点都连接这场比赛就行了,最多11个人左右吧,那么可以直接枚举谁是King,最保守而且没争议的方法就是暴力搜索枚举,就是01枚举,2^10*最大流时间,这个完全可以接受,然后就是网上说的那种直接枚举个数的说法,这个说法要明确一个问题,那就是如果当前有m个King,那么这m个不一定必须是后m个,也可以是中间的一些个,但是按照结论反推可以知道,这m个可以是后m个,也就是说即使不是后m个也可以转换成后m个,所以直接枚举后m就行,关键是要明白不是后m个是怎么可以转换成后m个的,我的想法一开始是找两个点,假设1..i..j..n,假如i是King,而j不是,那么就想办法吧ij的关系调换,就是让i变成不是King,而j是King,按照结论反推肯定是可以调换的,但是我想了很多方法都没有平衡掉ij之间的数字,找网上的也没有可以让我信服的,但是我自己有一个猜想,那就是我感觉可以按照贪心的方式去理解,越往后的称为King的代价就越小,也就是消耗的总的固定流量就越小,那么当然是越往后越可能了,枚举当然那是从后面开始,还有一个问题就是我感觉如果当前序列有k个可以称为King的话,那么一定可以转换成后k个,但是如果当前是后k个的话,不一定能往前转换,也就是我感觉后k个是最优的选择,就是类似那种后k个可以,但是还余出来一些资源没用,通过这些资源可以吧后k个中的一些挪到前面来,这样就产生了答案不以为的情况,但是直接枚举后k个是最优的方式,所有是正确的,这个也只是自己的感觉而已,已过想证明必须要把得分平衡掉。。。。下面是两种方法的代码,我的流用的是DINIC,估计姿势不优吧,速度和网上别人的速度比慢了很多.

DFS+DINIC

#include<queue>

#include<stdio.h>

#include<string.h>

#define N_node 150

#define N_edge 5000

#define INF 1000000000

using namespace std;

typedef struct

{

    int to ,cost ,next;

}STAR;

typedef struct

{

    int x ,t;

}DEP;

STAR E[N_edge];

DEP xin ,tou;

int list[N_node] ,listt[N_node] ,tot;

int deep[N_node];

void add(int a ,int b ,int c)

{

    E[++tot].to = b;

    E[tot].cost = c;

    E[tot].next = list[a];

    list[a] = tot;

    E[++tot].to = a;

    E[tot].cost = 0;

    E[tot].next = list[b];

    list[b] = tot;

}

int minn(int x ,int y)

{

    return x < y ? x : y;

}

bool BFS_DEEP(int s ,int t ,int n)

{

    memset(deep ,255 ,sizeof(deep));

    xin.x = s ,xin.t = 0;

    queue<DEP>q;

    q.push(xin);

    deep[s] = 0;

    while(!q.empty())

    {

        tou = q.front();

        q.pop();

        for(int k = list[tou.x] ;k ;k = E[k].next)

        {

            xin.x = E[k].to;

            xin.t = tou.t + 1;

            if(deep[xin.x] != -1 || !E[k].cost)

            continue;

            deep[xin.x] = xin.t;

            q.push(xin);

        }

    }

    for(int i = 0 ;i <= n ;i ++)

    listt[i] = list[i];

    return deep[t] != -1;

}

int DFS_Flow(int s ,int t ,int flow)

{

    if(s == t) return flow;

    int nowflow = 0;

    for(int k = listt[s] ;k ;k = E[k].next)

    {

        listt[s] = k;

        int c = E[k].cost;

        int to = E[k].to;

        if(!c || deep[to] != deep[s] + 1)

        continue;

        int tmp = DFS_Flow(to ,t ,minn(c ,flow - nowflow));

        nowflow += tmp;

        E[k].cost -= tmp;

        E[k^1].cost += tmp;

        if(nowflow == flow) break;

    }

    if(!nowflow) deep[s] = 0;

    return nowflow;

}

int DINIC(int s ,int t ,int n)

{

    int ans = 0;

    while(BFS_DEEP(s ,t ,n))

    {

        ans += DFS_Flow(s ,t ,INF);

    }

    return ans;

}

int now[15] ,num[15];

int Ans ,maxn ,n;

void Flow()

{

    memset(list ,0 ,sizeof(list));

    tot = 1;

    for(int i = 1 ;i <= n ;i ++)

    add(0 ,i ,num[i]);

    int nowid = n;

    for(int i = 1 ;i <= n ;i ++)

    for(int j = i + 1 ;j <= n ;j ++)

    {

        ++nowid;

        if(num[i] < num[j] && now[i])

        add(i ,nowid ,1);

        else if(num[j] < num[i] && now[j])

        add(j ,nowid ,1);

        else add(i ,nowid ,1) ,add(j ,nowid ,1);

        add(nowid ,n + n * (n - 1) / 2 + 1 ,1);

    }

    int flow = DINIC(0 ,n + n * (n - 1) / 2 + 1 ,n + n * (n - 1) / 2 + 1);

    if(flow == n * (n - 1) / 2)

    {

        int s = 0;

        for(int i = 1 ;i <= n ;i ++)

        s += now[i];

        if(Ans < s) Ans = s;

    }

    return ;

}

void DFS(int nowid)

{

    if(nowid == maxn + 1)

    {

        Flow();

        return;

    }

    now[nowid] = 0;

    DFS(nowid + 1);

    now[nowid] = 1;

    DFS(nowid + 1);

}

int main ()

{

    int t ,i ,nowid;

    char str[30];

    scanf("%d" ,&t);

    getchar();

    while(t--)

    {

        gets(str);

        int len = strlen(str);

        nowid = 0;

        for(i = 0 ;i < len ;i ++)

        {

            if(str[i] >= '0' && str[i] <= '9')

            {

                if(i == len - 1 || str[i+1] < '0' || str[i+1] > '9')

                num[++nowid] = str[i] - '0';

                else

                {

                    num[++nowid] = (str[i] - '0') * 10 + str[i+1] - '0';

                    i ++;

                }

            }

        }

        n = nowid;

        for(i = n ;i >= 1 ;i --)

        {

            if(num[i] == num[n])

            {

                maxn = i;

                now[i] = 1;

            }

            else now[i] = 0;

        }

        if(maxn == 1)

        {

            printf("%d\n" ,n);

            continue;

        }

        Ans = 0;

        DFS(1);

        printf("%d\n" ,Ans);

    }

    return 0;

}

枚举后几位+DINIC

#include<queue>

#include<stdio.h>

#include<string.h>

#define N_node 150

#define N_edge 5000

#define INF 1000000000

using namespace std;

typedef struct

{

    int to ,cost ,next;

}STAR;

typedef struct

{

    int x ,t;

}DEP;

STAR E[N_edge];

DEP xin ,tou;

int list[N_node] ,listt[N_node] ,tot;

int deep[N_node];

int num[15];

void add(int a ,int b ,int c)

{

    E[++tot].to = b;

    E[tot].cost = c;

    E[tot].next = list[a];

    list[a] = tot;

    E[++tot].to = a;

    E[tot].cost = 0;

    E[tot].next = list[b];

    list[b] = tot;

}

int minn(int x ,int y)

{

    return x < y ? x : y;

}

bool BFS_DEEP(int s ,int t ,int n)

{

    memset(deep ,255 ,sizeof(deep));

    xin.x = s ,xin.t = 0;

    queue<DEP>q;

    q.push(xin);

    deep[s] = 0;

    while(!q.empty())

    {

        tou = q.front();

        q.pop();

        for(int k = list[tou.x] ;k ;k = E[k].next)

        {

            xin.x = E[k].to;

            xin.t = tou.t + 1;

            if(deep[xin.x] != -1 || !E[k].cost)

            continue;

            deep[xin.x] = xin.t;

            q.push(xin);

        }

    }

    for(int i = 0 ;i <= n ;i ++)

    listt[i] = list[i];

    return deep[t] != -1;

}

int DFS_Flow(int s ,int t ,int flow)

{

    if(s == t) return flow;

    int nowflow = 0;

    for(int k = listt[s] ;k ;k = E[k].next)

    {

        listt[s] = k;

        int c = E[k].cost;

        int to = E[k].to;

        if(!c || deep[to] != deep[s] + 1)

        continue;

        int tmp = DFS_Flow(to ,t ,minn(c ,flow - nowflow));

        nowflow += tmp;

        E[k].cost -= tmp;

        E[k^1].cost += tmp;

        if(nowflow == flow) break;

    }

    if(!nowflow) deep[s] = 0;

    return nowflow;

}

int DINIC(int s ,int t ,int n)

{

    int ans = 0;

    while(BFS_DEEP(s ,t ,n))

    {

        ans += DFS_Flow(s ,t ,INF);

    }

    return ans;

}

int Flow(int now ,int n)

{

    memset(list ,0 ,sizeof(list));

    tot = 1;

    int s = 0 ,t = n + n * (n - 1) / 2 + 1;

    for(int i = 1 ;i <= n ;i ++)

    add(s ,i ,num[i]);

    int nowid = n;

    for(int i = 1 ;i <= n ;i ++)

    for(int j = i + 1 ;j <= n ;j ++)

    {

        ++nowid;

        if(num[i] < num[j] && i >= now)

        add(i ,nowid ,1);

        else if(num[j] < num[i] && j >= now)

        add(j ,nowid ,1);

        else add(i ,nowid ,1) ,add(j ,nowid ,1);

        add(nowid ,t ,1);

    }

    return DINIC(s ,t ,t);

}

int main ()

{

    int i ,nowid ,t;

    char str[30];

    scanf("%d" ,&t);

    getchar();

    while(t--)

    {

        gets(str);

        int len = strlen(str);

        nowid = 0;

        for(i = 0 ;i < len ;i ++)

        {

            if(str[i] >= '0' && str[i] <= '9')

            {

                if(i == len - 1 || str[i+1] < '0' || str[i + 1] > '9')

                num[++nowid] = str[i] - '0';

                else

                {

                    num[++nowid] = (str[i] - '0') * 10 + str[i+1] - '0';

                    i ++;

                }

            }

        }

        int list;

        for(i = nowid ;i >= 1 ;i --)

        if(num[i] == num[nowid]) list = i;

        if(list == 1)

        {

            printf("%d\n" ,nowid);

            continue;

        }

        for(i = 1 ;i <= nowid ;i ++)

        {

            if(Flow(i ,nowid) == nowid * (nowid - 1) / 2)

            break;

        }

        printf("%d\n" ,nowid - i + 1);

    }

    return 0;

}

POJ2669不错的最大流 竞赛问题(枚举King的个数)的更多相关文章

  1. POJ 3185 The Water Bowls(高斯消元-枚举变元个数)

    题目链接:http://poj.org/problem?id=3185 题意:20盏灯排成一排.操作第i盏灯的时候,i-1和i+1盏灯的状态均会改变.给定初始状态,问最少操作多少盏灯使得所有灯的状态最 ...

  2. Educational Codeforces Round 35 B. Two Cakes【枚举/给盘子个数,两份蛋糕块数,最少需要在每个盘子放几块蛋糕保证所有蛋糕块都装下】

    B. Two Cakes time limit per test 1 second memory limit per test 256 megabytes input standard input o ...

  3. hdu 2058 枚举区间和个数

    题意:       给你两个数n,m,意思是有一个序列长度n,他是1 2 3 4 ...n,然后让你输出所有连续和等于m的范围. 思路:       是个小水题,随便写几个数字就能发现规律了,我们可以 ...

  4. POJ2699 The Maximum Number of Strong Kings

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2102   Accepted: 975 Description A tour ...

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

    http://poj.org/problem?id=2699 题意: 一场联赛可以表示成一个完全图,点表示参赛选手,任意两点u, v之间有且仅有一条有向边(u, v)或( v, u),表示u打败v或v ...

  6. BNU 33693——Problemsetting——————【枚举+最大流】

    Problemsetting Time Limit: 5000ms Memory Limit: 131072KB 64-bit integer IO format: %lld      Java cl ...

  7. poj 2699 The Maximum Number of Strong Kings 枚举 最大流

    题目链接 题意 对于一个竞赛图(有向完全图),其顶点是选手,边是比赛,边\(e=(u,v)\)代表该场比赛中\(u\)战胜\(v\). 现定义选手的分数为其战胜的人的个数(即竞赛图中点的出度).并且定 ...

  8. Spring Cloud Alibaba:Sentinel实现熔断与限流

    一.什么是Sentinel Sentinel,中文翻译为哨兵,是为微服务提供流量控制.熔断降级的功能,它和Hystrix提供的功能一样,可以有效的解决微服务调用产生的“雪崩效应”,为微服务系统提供了稳 ...

  9. 最大流 总结&&做题记录

    最近一直很忙,为了节省时间,从今以后的题解会 一个专题 写一篇. 刷了一些题后,有了以下总结: 模型要点: 1.构造流量平衡,在满足流量平衡的情况下,找到要让什么最大. 2.一般用于判断性问题,即所有 ...

随机推荐

  1. 数据库事务 ACID属性、数据库并发问题和四种隔离级别

    数据库事务 ACID属性.数据库并发问题和四种隔离级别 数据库事务 数据库事务是一组逻辑操作单元,使数据从一种状态变换到另一种状态 一组逻辑操作单元:一个或多个DML操作 事务处理原则 保证所有事务都 ...

  2. 1.mysql读写

    一.数据库读取(mysql) 参数 接受 作用 默认 sql or table_name string 读取的表名,或sql语句 无 con 数据库连接 数据库连接信息 无 index_col Int ...

  3. Srping源码之BeanFactory.getBean

    本文是针对Srping的BeanFactory.getBean来进行源码解析,如果您是第一次看请先看一下XMLBeanFactory解析:https://www.cnblogs.com/technol ...

  4. MyEclipse安装过程

    1.安装JDK并配置环境变量 下载地址: https://www.oracle.com/technetwork/java/javase/downloads/index.html ①点击download ...

  5. 妙味课上利用splice进行数组去重为什么要 j--

    var arr = [ 1,2,2,4,4,5,8,8,9,0,4,4 ]; for ( var i=0; i<arr.length; i++ ) { for ( var j=i+1; j< ...

  6. Edge 浏览器开发工具新增了 3D 视图,你尝试了吗?

    在使用开发者工具的时候,无意间发现了一个3D面板,如下: 仔细想想,这应该是之前 Firefox 的特性啊,不过后来去掉了,说是太难维护,没想到 Edge 也添加了这个特性. 使用该特性,你可以完成如 ...

  7. Mybatis-plus 上

    Mybatis-plus 上 简介 1.什么是Mybatis-plus MyBatis-Plus(简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发 ...

  8. Java网络编程快速上手(SE基础)

    参考资料:百度百科TCP协议 本文涉及Java IO流.异常的知识,可参考我的另外的博客 一文简述Java IO 一文简述JAVA内部类和异常 1.概述 计算机网络相关知识: OSI七层模型 一个报文 ...

  9. 【CTF】Pwn入门 XCTF 部分writeup

    碎碎念 咕咕咕了好久的Pwn,临时抱佛脚入门一下. 先安利之前看的一个 Reverse+Pwn 讲解视频 讲的还是很不错的,建议耐心看完 另外感觉Reverse和Pwn都好难!! 不,CTF好难!! ...

  10. 「HTML+CSS」--自定义加载动画【016】

    前言 Hello!小伙伴! 首先非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出- 哈哈 自我介绍一下 昵称:海轰 标签:程序猿一只|C++选手|学生 简介:因C语言结识编程,随后转入计算机 ...