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 (最大流+枚举)的更多相关文章

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

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

  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. poj 2699 The Maximum Number of Strong Kings 枚举 最大流

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

  4. poj 2699 The Maximum Number of Strong Kings【最大流+枚举】

    因为n很小所以从大到小枚举答案.(从小到大先排个序,因为显然胜利场次越多越容易成为strong king.然后对于每个枚举出来的ans建图.点分别表示人和比赛.s向所有人连接流量为胜利场次的边,所有比 ...

  5. POJ 2699 The Maximum Number of Strong Kings ——网络流

    一定存在一种最优方案,使得分数前几个人是SK 所以我们可以二分答案或者枚举,然后就是经典的网络流建模. 另:输入很Excited #include <cstdio> #include &l ...

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

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

  7. POJ2699 The Maximum Number of Strong Kings

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

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

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

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

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

随机推荐

  1. SDOI 2016 Round1 Day2

    生成魔咒 /* 后缀数组+双向链表 参照:https://blog.csdn.net/clove_unique/article/details/53911757 */ #include<cstd ...

  2. 11.事件驱动events

    事件驱动events ==> events.EventEmitter, EventEmitter 的核心就是事件发射与事件监听器功能的封装更详细的 API 文档参见 http://nodejs. ...

  3. Android 使用动画效果后的控件位置处理 类似系统通知栏下拉动画

    Android的动画的使用,请参考.Android的动画,在设计方面,我有点不太理解,觉得这样搞很怪,因为在控件动画后,即使设置了停留在动画结束时的位置,我们也确实看到了控件停在那个位置,但其实该控件 ...

  4. python 对文件的操作

    观看的技术文来源:http://www.cnblogs.com/alex3714/articles/5717620.htmlimport sys# data = open("yesterda ...

  5. Linux登录失败处理功能

     本文要实现的功能:如果有人恶意尝试破解你的服务器密码,那么这个功能就能帮你起到一定的作用,当尝试密码错误超过设定的次数后,就会锁定该账户多长时间(自行设定),时间过后即可自行解锁,这样可以增加攻击者 ...

  6. Lucene.net之解决锁的问题

    public sealed class SearchIndexManager { private static readonly SearchIndexManager searchManager=ne ...

  7. Cisco设备开启telnet登录

    思科设备怎么开启telnet登录 configuration line vty 0 4SW1(config-line)#transp input telne

  8. 解决“The remote certificate is invalid according to the validation procedure”问题

    在用HttpClient发起https请求时,遭遇了“The remote certificate is invalid according to the validation procedure”异 ...

  9. 阿里云 elastic search 重启 过程

    阿里云 es 重启 elasticsearch  重启 过程 实例变更中   53.13%   准备ECS资源 已完成节点数:4/4, 进度:100%     准备容器服务 进度:100%     变 ...

  10. Farthest Nodes in a Tree ---LightOj1094(树的直径)

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1094 Given a tree (a connected graph with no ...