poj2699:http://poj.org/problem?id=2699

题意:n个人,进行n*(n-1)/2场比赛,赢一场则得到一分。如果一个人打败了所有比他分数高的对手,或者他就是分数最高的,那么他就是strong kind。现在给你每个人的得分,问你最多有多少个strong kind。

题解:自己没有思路,看了别人的题解,才勉强理解了。首先,肯定让得分高的成为strong king,因为概率比较大,然后就是怎建图了。假如,我们已经知道了,有m个strong kind,那么这m个人一定是后m个,所以,我们只要判断这m个是否满足条件就可以了,由于n很小,所以可以直接枚举ans。接下来就是建图,人作为一个点,与s建立一边,容量就是得分,然后比赛作为一种点,和t连接,容量是1,然后开始枚举ans,对于后ans个人来说,每个人i对于比他分高的选手j,都必须赢,所以对于i,j之间的比赛,i必须赢,所以i--mp[i][j](表示ij之间比赛的编号)建立一边,容量是1,然后对于剩余的比赛来说,i,j都可以赢,所以i,j都要建立一边到mp[i][j]容量是1,然后跑网络流,如果跑出的maxflow==n*(n-1)/2,说明这种方式是满足的,直接输出就可以了。这一题的读入不是很规范,数字之间不是严格的一个空格,可能有多个空格。

 #include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<string>
#define INF 100000000
using namespace std;
const int N=;
const int M=;
struct Node{
int v;
int f;
int next;
}edge[M];
int n,m,u,v,tt,cnt,sx,ex;
int head[],pre[];
int g[],f[N],mp[][];//根据题目要求申请
void init(){
cnt=;
memset(head,-,sizeof(head));
memset(f,,sizeof(f));
}
void add(int u,int v,int w){
edge[cnt].v=v;
edge[cnt].f=w;
edge[cnt].next=head[u];
head[u]=cnt++;
edge[cnt].f=;
edge[cnt].v=u;
edge[cnt].next=head[v];
head[v]=cnt++;
}
bool BFS(){
memset(pre,,sizeof(pre));
pre[sx]=;
queue<int>Q;
Q.push(sx);
while(!Q.empty()){
int d=Q.front();
Q.pop();
for(int i=head[d];i!=-;i=edge[i].next ){
if(edge[i].f&&!pre[edge[i].v]){
pre[edge[i].v]=pre[d]+;
Q.push(edge[i].v);
}
}
}
return pre[ex]>;
}
int dinic(int flow,int ps){
int f=flow;
if(ps==ex)return f;
for(int i=head[ps];i!=-;i=edge[i].next){
if(edge[i].f&&pre[edge[i].v]==pre[ps]+){
int a=edge[i].f;
int t=dinic(min(a,flow),edge[i].v);
edge[i].f-=t;
edge[i^].f+=t;
flow-=t;
if(flow<=)break;
} }
if(f-flow<=)pre[ps]=-;
return f-flow;
}
int solve(){
int sum=;
while(BFS())
sum+=dinic(INF,sx);
return sum;
}
void build(int num){
init();
for(int i=;i<=n;i++)
add(,i,g[i]);
for(int i=;i<=tt;i++)
add(i+n,n+tt+,);
for(int i=n-num+;i<=n;i++)
for(int j=i+;j<=n;j++){
if(g[j]>g[i]){
f[mp[i][j]]=;
add(i,mp[i][j]+n,);
}
}
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++){
if(!f[mp[i][j]]){
add(i,mp[i][j]+n,);
add(j,mp[i][j]+n,);
}
}
}
string str;
int main() {
int T;
scanf("%d",&T);
getchar();
while(T--) {
n=;
getline(cin,str);
int len=str.length();
for(int i=;i<len;i++){
if(str[i]>=''&&str[i]<='')
g[++n]=str[i]-'';
}
tt=;
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++)
mp[i][j]=++tt;
sx=,ex=n+tt+;
int i;
for(i=n;i>;i--){
build(i);
if(solve()==tt)break;
}
printf("%d\n",i);
}
return ;
}

The Maximum Number of Strong Kings的更多相关文章

  1. POJ2699 The Maximum Number of Strong Kings

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

  2. 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 ...

  3. 【POJ2699】The Maximum Number of Strong Kings(网络流)

    Description A tournament can be represented by a complete graph in which each vertex denotes a playe ...

  4. POJ2699:The Maximum Number of Strong Kings(枚举+贪心+最大流)

    The Maximum Number of Strong Kings Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2488 ...

  5. POJ2699 The Maximum Number of Strong Kings(最大流)

    枚举所有Strong King的状态(最多1024种左右),然后判断是否合法. 判定合法用网络流,源点-比赛-人-汇点,这样连边. 源点向每场比赛连容量为1的边: 如果一场比赛,A和B,A是Stron ...

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

    网络流/最大流/二分or贪心 题目大意:有n个队伍,两两之间有一场比赛,胜者得分+1,负者得分+0,问最多有几只队伍打败了所有得分比他高的队伍? 可以想到如果存在这样的“strong king”那么一 ...

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

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

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

    题意:有n(n<=10)个选手,两两之间打比赛,共有n*(n-1)/2场比赛,赢一场得1分.给出每个人最后的得分.求有多少个定义如下的strong king:赢了所有得分比自己高的人或本身就是分 ...

  9. 「POJ 2699」The Maximum Number of Strong Kings

    题目链接 戳我 \(Describe\) 一场联赛可以表示成一个完全图,点表示参赛选手,任意两点u, v之间有且仅有一条有向边\((u, v)\)或\((v, u)\),表示\(u\)打败\(v\)或 ...

随机推荐

  1. Windows 7系统下局域网文件共享设置方法

    今天给家里增添了一台组装机,小试了一下win7局域网文件共享功能,很爽的说. 记录一下实现方法: 1.关闭防火墙 2.启用共享. 控制面板 – 网络和共享中心 – 更改高级共享设置,将图中的几个选项选 ...

  2. NDK开发之获得域和方法描述符

    在NDK开发之调用方法和NDK开发之访问域两篇博客中,我们在获得域ID和方法ID时都需要一个叫做描述符的参数,那么在实际开发中我们怎么知道我们要调用的域或者方法的描述符呢? 一个简单的方法就是使用Ja ...

  3. linux bash下 快捷键

    c + a # 光标跳转到最左 c + e # 光标跳转到最后 c + w # 删除最后输入的单词 c + u # 删除整行 c + k # 删除光标到末尾 c + l # 清屏 c + z # 挂起 ...

  4. LAMP网站架构方案分析

    本文引自:http://www.williamlong.info/archives/1908.html LAMP(Linux-Apache-MySQL-PHP)网站架构是目前国际流行的Web框架,该框 ...

  5. 解决Visual Studio 找不到报表控件、rdlc中文乱码

    找回报表控件 运行安装程序中的 ..\packages\Reporting Services\RVAddon.msi 工具栏,右键选择ReportViewer,注意选择的版本 如果不能编辑报表文件(. ...

  6. mybatis中几种typeHandler的定义使用

    1.存储到数据库, 将LONG数组转换成字符串;从数据库获取数据, 将字符串转为LONG数组 package com.winturn.utils.handler; import java.sql.Ca ...

  7. UML图基本类型

    use case model用例模型 analysiss model分析模型 design model设计模型 implementation model实现模型 deployment model部署模 ...

  8. [访问系统] C#计算机信息类ComputerInfo (转载)

    下载整个包,只下载现有类是不起作用的 http://www.sufeinet.com/thread-303-1-1.html 点击此处下载 using System; using System.Man ...

  9. C#中堆和栈的区别分析(有待更新总结)

    转载:http://blog.csdn.net/zevin/article/details/5721495 一.预备知识-程序的内存分配 一个由C/C++编译的程序占用的内存分为以下几个部分 1.栈区 ...

  10. SQL语句一之建库

    USE master --转到系统表goIF EXISTS(SELECT *  FROM sysdatabases WHERE name ='Test') --查询是否存在Test数据库DROP DA ...