POJ 2699 The Maximum Number of Strong Kings (最大流+枚举)
http://poj.org/problem?id=2699
题意:
一场联赛可以表示成一个完全图,点表示参赛选手,任意两点u, v之间有且仅有一条有向边(u, v)或( v, u),表示u打败v或v打败u。一个选手的得分等于被他打败的选手总数。一个选手被称为“strong king”当且仅当他打败了所有比他分高的选手。分数最高的选手也是strong king。现在给出某场联赛所有选手的得分序列,由低到高,问合理安排每场比赛的结果后最多能有几个strong king。已知选手总数不超过10个。
思路:
选手总数很少,我们可以考虑枚举。
枚举当前strong king的个数为num个,那么可能存在分数最高的num个人是strong king,其余情况也可能存在,但这种情况是最可能的,只要满足这个就可以了。
建立源点和汇点,源点和每场比赛相连(比赛共有n*(n-1)/2场),容量为1,汇点和选手相连,容量为选手分数。
那么比赛和选手怎么连接呢?
如果选手i是strong king,那么凡是分数比他高的人,他都必须要赢,此时把这场比赛和i相连。
如果i和j都不是strong king,那么这场比赛无所谓谁输谁赢,将这场比赛和i和j都连起来就可以。
最后跑最大流,如果等于n*(n-1)/2,就是可以的。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<sstream>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
using namespace std;
typedef long long LL;
typedef pair<int,int> pll;
const int INF=0x3f3f3f3f;
const int maxn=+; int n;
int score[maxn];
int com[maxn][maxn]; struct Edge
{
int from,to,cap,flow;
Edge(int u,int v,int w,int f):from(u),to(v),cap(w),flow(f){}
}; struct Dinic
{
int n,m,s,t;
vector<Edge> edges;
vector<int> G[maxn];
bool vis[maxn];
int cur[maxn];
int d[maxn]; void init(int n)
{
this->n=n;
for(int i=;i<n;++i) G[i].clear();
edges.clear();
} void AddEdge(int from,int to,int cap)
{
edges.push_back( Edge(from,to,cap,) );
edges.push_back( Edge(to,from,,) );
m=edges.size();
G[from].push_back(m-);
G[to].push_back(m-);
} bool BFS()
{
queue<int> Q;
memset(vis,,sizeof(vis));
vis[s]=true;
d[s]=;
Q.push(s);
while(!Q.empty())
{
int x=Q.front(); Q.pop();
for(int i=;i<G[x].size();++i)
{
Edge& e=edges[G[x][i]];
if(!vis[e.to] && e.cap>e.flow)
{
vis[e.to]=true;
d[e.to]=d[x]+;
Q.push(e.to);
}
}
}
return vis[t];
} int DFS(int x,int a)
{
if(x==t || a==) return a;
int flow=, f;
for(int &i=cur[x];i<G[x].size();++i)
{
Edge &e=edges[G[x][i]];
if(d[e.to]==d[x]+ && (f=DFS(e.to,min(a,e.cap-e.flow) ) )>)
{
e.flow +=f;
edges[G[x][i]^].flow -=f;
flow +=f;
a -=f;
if(a==) break;
}
}
return flow;
} int Maxflow(int s,int t)
{
this->s=s; this->t=t;
int flow=;
while(BFS())
{
memset(cur,,sizeof(cur));
flow +=DFS(s,INF);
}
return flow;
}
}DC; int solve(int num,int cnt)
{
int tot=n*(n-)/;
int src=,dst=n+tot+;
DC.init(dst+); for(int i=;i<=n;i++)
DC.AddEdge(i,dst,score[i]);
for(int j=n+;j<=cnt;j++)
DC.AddEdge(src,j,); for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++)
{
if(score[i]>score[j] && j>n-num) DC.AddEdge(com[i][j],j,);
else if(score[i]<score[j] && i>n-num) DC.AddEdge(com[i][j],i,);
else
{
DC.AddEdge(com[i][j],i,);
DC.AddEdge(com[i][j],j,);
}
}
return DC.Maxflow(src,dst)==tot;
} int main()
{
//freopen("D:\\input.txt","r",stdin);
int T;
scanf("%d",&T);
getchar();
while(T--)
{
n=;
string str;
getline(cin,str);
stringstream ss(str);
int x;
while(ss>>x) score[++n]=x; int num=n;
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++)
com[i][j]=com[j][i]=++num; for(int i=n;i>=;i--)
{
if(solve(i,num)) {printf("%d\n",i);break;}
}
}
return ;
}
POJ 2699 The Maximum Number of Strong Kings (最大流+枚举)的更多相关文章
- 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 Description
The Maximum Number of Strong Kings Description A tournament can be represented by a complete graph ...
- poj 2699 The Maximum Number of Strong Kings 枚举 最大流
题目链接 题意 对于一个竞赛图(有向完全图),其顶点是选手,边是比赛,边\(e=(u,v)\)代表该场比赛中\(u\)战胜\(v\). 现定义选手的分数为其战胜的人的个数(即竞赛图中点的出度).并且定 ...
- poj 2699 The Maximum Number of Strong Kings【最大流+枚举】
因为n很小所以从大到小枚举答案.(从小到大先排个序,因为显然胜利场次越多越容易成为strong king.然后对于每个枚举出来的ans建图.点分别表示人和比赛.s向所有人连接流量为胜利场次的边,所有比 ...
- POJ 2699 The Maximum Number of Strong Kings ——网络流
一定存在一种最优方案,使得分数前几个人是SK 所以我们可以二分答案或者枚举,然后就是经典的网络流建模. 另:输入很Excited #include <cstdio> #include &l ...
- 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
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2102 Accepted: 975 Description A tour ...
- 【POJ2699】The Maximum Number of Strong Kings(网络流)
Description A tournament can be represented by a complete graph in which each vertex denotes a playe ...
- 【POJ】【2699】The Maximum Number of Strong Kings
网络流/最大流/二分or贪心 题目大意:有n个队伍,两两之间有一场比赛,胜者得分+1,负者得分+0,问最多有几只队伍打败了所有得分比他高的队伍? 可以想到如果存在这样的“strong king”那么一 ...
随机推荐
- 自定义事件类EventManager (TS中...args的使用例子)
一个自定义事件类 初衷是使用Egret的事件有两点比较麻烦 1 在事件处理函数时,需要从e中获取data hander(e:egret.Event){ let data = e.data; } 2 ...
- Add a try-catch with Mono Cecil
Adding exception handlers with Mono.Cecil is not difficult, it just requires you to know how excepti ...
- 【BZOJ4553】[Tjoi2016&Heoi2016]序列 cdq分治+树状数组
[BZOJ4553][Tjoi2016&Heoi2016]序列 Description 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值可能 ...
- c# comboBox与数据库中的数据绑定
private void comBoxBinding() { SqlConnection connection = this.getConnection(); connection.Open(); S ...
- java合并两个升序数组为一个新的有序数组
转自:http://blog.csdn.net/laozhaokun/article/details/37531247 题目:有两个有序数组a,b,现需要将其合并成一个新的有序数组. 简单的思路就是先 ...
- 从零打造在线网盘系统之Hibernate框架起步
欢迎浏览Java工程师SSH教程从零打造在线网盘系统系列教程,本系列教程将会使用SSH(Struts2+Spring+Hibernate)打造一个在线网盘系统,本系列教程是从零开始,所以会详细以及着重 ...
- 解决Ubuntu14.04下vi编辑器不能使用方向键和退格键问题
参考:http://blog.sina.com.cn/s/blog_7d0c2fed01010zbi.html 系统:Ubuntu14.04 使用vi命令时,不能正常编辑文件,使用方向键时老是出现很多 ...
- C++ Design Pattern: What is a Design Pattern?
Q: What is a Design Pattern? A: Design Patterns represent solutions to problems what arise when deve ...
- mysql 数据操作 单表查询 concat()函数 定义显示格式
#定义显示格式 concat() 函数用于连接字符串 类似于python 格式化操作print("姓名:%s" % name)或者 用,拼接一个一个的变量print("a ...
- LVS和nginx反向代理网站架构
LVS和nginx反向代理网站架构 nginx反向代理和lvs的dr都存在单点,要keepalived做高可用,但是成本高了 f