POJ 2699 - The Maximum Number of Strong Kings(网络流‘最大流)
来源:互联网 发布:蜂窝数据栏下找不到app 编辑:程序博客网 时间:2024/05/16 01:50
题目:
http://poj.org/problem?id=2699
题意;
比赛中每个人的得分为他打败的人数,得分最高的人可称为 strongking,打败得分最高的人也可以成为SK,给出比赛中每个人的得分,从小到大排,求出最大可能的SK的人数。
思路:
好难想的建图> <
有人说:一般遇到竞赛图,网络流的可能性较大,因为竞赛图中的条件都与点的度数有关。
建图:左边是人(s,i,scor[i]),右边是比赛(j,t,1)。接着枚举答案(n<=10, 所以此处应该想到枚举),让后ans人成为SK,ans中的a,b,若scor[a] < scor[b],则建边(a,comp[a][b],1),因为a比b分少要成为Sk就要打败b。(comp记录的是比赛序号)。对于剩下的比赛,任意连(a,comp[a][b], 1),(b, comp[a][b], 1).当maxflow == (n*(n-1))/2时输出答案。
AC.
#include <iostream>#include <cstdio>#include <vector>#include <cstring>#include <string>#include <cmath>#include <algorithm>#include <queue>#include <sstream>using namespace std;const int INF = 1e9;string ss;int n, tot;int scor[15], v[2000], comp[15][15];struct edge { int to, cap, rev; edge(int tt, int cc, int rr) { to = tt; cap = cc; rev = rr; }};vector<edge> g[2000];int level[2000];int iter[2000];void addedge(int from, int to, int cap){ g[from].push_back(edge(to, cap, g[to].size())); g[to].push_back(edge(from, 0, g[from].size()-1));}void bfs(int s){ memset(level, -1, sizeof(level)); queue<int> que; level[s] = 0; que.push(s); while(!que.empty()) { int v = que.front(); que.pop(); for(int i = 0; i < g[v].size(); ++i) { edge &e = g[v][i]; if(e.cap > 0 && level[e.to] < 0) { level[e.to] = level[v] + 1; que.push(e.to); } } }}int dfs(int v, int t, int f){ if(v == t) return f; for(int &i = iter[v]; i < g[v].size(); ++i) { edge &e = g[v][i]; if(e.cap > 0 && level[v] < level[e.to]) { int d = dfs(e.to, t, min(f, e.cap)); if(d > 0) { e.cap -= d; g[e.to][e.rev].cap += d; return d; } } } return 0;}int max_flow(int s, int t){ int flow = 0; while(1) { bfs(s); if(level[t] < 0) return flow; memset(iter, 0, sizeof(iter)); int f; while( (f = dfs(s, t, INF)) > 0) { flow += f; } }}void build(int s, int t, int num){ for(int i = 0; i <= 2000; ++i) g[i].clear(); memset(v, 0, sizeof(v)); for(int i = 1; i <= n; ++i) { addedge(s, i, scor[i]); } for(int i = 1; i <= tot; ++i) { addedge(i+n, t, 1); } for(int i = n-num+1; i <= n; ++i) { for(int j = i + 1; j <= n; ++j) { if(scor[i] < scor[j]) { v[comp[i][j]] = 1; addedge(i, comp[i][j]+n, 1); } } } for(int i = 1; i <= n; ++i) { for(int j = i + 1; j <= n; ++j) { if(!v[comp[i][j]]) { addedge(i, comp[i][j]+n, 1); addedge(j, comp[i][j]+n, 1); } } }}int main(){ //freopen("in", "r", stdin); int T; scanf("%d", &T); getchar(); while(T--) { getline(cin, ss); stringstream str(ss); int a; n = 0; while(str>>a) { scor[++n] = a; } tot = 0; for(int i = 1; i <= n; ++i) { for(int j = i+1; j <= n; ++j) { comp[i][j] = ++tot; } } int sum = (n*(n-1))/2; int s = 0, t = tot + n + 1; for(int i = n; i >= 1; --i) { build(s, t, i); if(max_flow(s, t) == sum) { printf("%d\n", i); break; } } } return 0;}
0 0
- POJ 2699 The Maximum Number of Strong Kings(最大流)
- POJ 2699The Maximum Number of Strong Kings(最大流)
- POJ 2699 The Maximum Number of Strong Kings 最大流
- poj 2699 The Maximum Number of Strong Kings 网络流
- POJ 2699 - The Maximum Number of Strong Kings(网络流‘最大流)
- POJ 2699 The Maximum Number of Strong Kings(最大流)
- POJ 2699 The Maximum Number of Strong Kings 竞赛图+最大流
- [省选前题目整理][POJ 2699]The Maximum Number of Strong Kings(暴力枚举+最大流)
- POJ 2699 The Maximum Number of Strong Kings 最大流 枚举
- poj 2699 The Maximum Number of Strong Kings(最大流,建图)
- POJ 2699 The Maximum Number of Strong Kings(枚举+最大流)
- POJ 2699 The Maximum Number of Strong Kings(枚举/二分+最大流)
- POJ 2699 The Maximum Number of Strong Kings 网络流 竞赛图
- POJ 2699 The Maximum Number of Strong Kings (网络流)
- poj 2699 The Maximum Number of Strong Kings 【二分 + 竞赛图建模判断是否满流】
- POJ 2699 The Maximum Number of Strong Kings
- poj 2699 The Maximum Number of Strong Kings
- POJ 2699 The Maximum Number of Strong Kings
- JAVA学习第3天(5)继承相关:super用法,复写override
- MATLAB2015分布式计算服务系统安装与应用
- Tomcat 配置多个服务 server 起多个应用
- Ubuntu14.10搭建LAMP平台以及虚拟主机的设置
- Java高级篇整理
- POJ 2699 - The Maximum Number of Strong Kings(网络流‘最大流)
- 程序员面试宝典(19)-反转链表
- web.xml配置详解
- Tomcat 连接池
- SQL on HBase -- phoenix 之分页查询
- Mac OS X中MacPorts安装和使用
- app文件组成
- Android 绑定类型服务---绑定服务
- Java BlockingQueue