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个人一定是后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的更多相关文章
- POJ2699 The Maximum Number of Strong Kings
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2102 Accepted: 975 Description A tour ...
- 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 ...
- 【POJ2699】The Maximum Number of Strong Kings(网络流)
Description A tournament can be represented by a complete graph in which each vertex denotes a playe ...
- POJ2699:The Maximum Number of Strong Kings(枚举+贪心+最大流)
The Maximum Number of Strong Kings Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2488 ...
- POJ2699 The Maximum Number of Strong Kings(最大流)
枚举所有Strong King的状态(最多1024种左右),然后判断是否合法. 判定合法用网络流,源点-比赛-人-汇点,这样连边. 源点向每场比赛连容量为1的边: 如果一场比赛,A和B,A是Stron ...
- 【POJ】【2699】The Maximum Number of Strong Kings
网络流/最大流/二分or贪心 题目大意:有n个队伍,两两之间有一场比赛,胜者得分+1,负者得分+0,问最多有几只队伍打败了所有得分比他高的队伍? 可以想到如果存在这样的“strong king”那么一 ...
- POJ 2699 The Maximum Number of Strong Kings (最大流+枚举)
http://poj.org/problem?id=2699 题意: 一场联赛可以表示成一个完全图,点表示参赛选手,任意两点u, v之间有且仅有一条有向边(u, v)或( v, u),表示u打败v或v ...
- POJ - 2699 The Maximum Number of Strong Kings (最大流+枚举)
题意:有n(n<=10)个选手,两两之间打比赛,共有n*(n-1)/2场比赛,赢一场得1分.给出每个人最后的得分.求有多少个定义如下的strong king:赢了所有得分比自己高的人或本身就是分 ...
- 「POJ 2699」The Maximum Number of Strong Kings
题目链接 戳我 \(Describe\) 一场联赛可以表示成一个完全图,点表示参赛选手,任意两点u, v之间有且仅有一条有向边\((u, v)\)或\((v, u)\),表示\(u\)打败\(v\)或 ...
随机推荐
- MYSQL 学习笔记1 -----mysqladmin -uroot -p status|extended-status
root@server1 ~]# mysqladmin -uroot -p status -i -r extended-status|grep Handler_commit Enter passwor ...
- 软件版本中的Alpha,Beta,RC,Trial是什么意思?
版本号: V(Version):即版本,通常用数字表示版本号.(如:EVEREST Ultimate v4.20.1188 Beta ) Build:用数字或日期标示版本号的一种方式.(如:VeryC ...
- VC/MFC 下 递归遍历目录下的所有子目录及文件
在MFC下要实现文件夹的递归遍历,可用CFileFind类,依次读取文件夹下的子文件夹和文件,并判断通过判断是文件夹还是文件来决定递归遍历.递归遍历代码如下: /******************* ...
- Java基础知识强化之IO流笔记35:InputStreamReader(Reader字符流的子类)2种read数据方式
1. InputStreamReader(Reader字符流的子类)2种read数据方式: InputStreamReader的read方法: int read():一次读取一个字符 int read ...
- Setup Tensorflow with GPU on Mac OSX 10.11
Setup Tensorflow with GPU on OSX 10.11 环境描述 电脑:MacBook Pro 15.6 CPU: 2.7GHz 显卡: GT 650m 系统:OSX 10.11 ...
- window和Linux下的软链接
window下开启软链接命令: mklink /J "D:\IdeaProjects\bms_work\smartcity_govnet\base_web\target\base_web\ ...
- tomcat中jsp编译
tomcat运行的工程中,jsp替换文件后可能不起作用.原因是jsp也是需要编译的.编译后的文件存放在tomcat/work文件夹下.如果替换不起作用,可以将work文件夹下的内容删除掉,重新启tom ...
- IE6 中的最大最小寬度和高度 css 高度 控制(兼容版本)
/* 最小寬度 */.min_width{min-width:300px; /* sets max-width for IE */ _width:expression(document.body.cl ...
- js实现FileUpload选择图片后预览功能
当asp.net的FileUpload选择一个图片后不需要上传就能显示出图片的预览功能, 代码: <%@ Page Language="C#" AutoEventWireup ...
- Winedt 7.0 Build: 20120321 永久试用方法 WinEdt 7.0 破解
该方法,不是破解. 因为WinEdt试用版与正式版功能无异. 所以,该方法是 通过更新注册表信息,重置安装时间. 也就是重新获取31天的试用期时长. 方法如下: 1.用管理员权限打开CMD. 2.运行 ...