题目大意:有n支足球队,已知每支球队的已胜场数和任意两支球队之间还需要的比赛场数a[i][j],求最终可能夺冠的所有球队。

题目分析:枚举所有的球队,对于球队 i 让它在接下来的比赛中全部获胜,如果这样球队 i 还不能夺冠,那么 i 不是要找的,否则,就是答案。这道题可以建立公平分配问题的模型。将任意两个之间还有比赛的球队视作一个节点X(由u和v构成,即a[u][v]>0),则对于X有两个选择:u获胜或v获胜。这样的一个X相当于一个“任务”,对于每个任务X有两个“处理器”(u和v)供选择。建图如下:增加源点s和汇点t,由s出发向所有的X均连一条弧,容量为a[u][v],然后由X出发向其对应的u和v各连一条容量为无穷大的弧,最后对每个球队u都连一条指向汇点t的弧,容量为total-win(u),其中,total为 i 已经获胜的场数,win(u)为u已经获胜的场数。当源点出发的所有弧都饱和时,当前枚举的球队 i 则可能夺冠。

代码如下:

# include<iostream>
# include<cstdio>
# include<cmath>
# include<string>
# include<vector>
# include<list>
# include<set>
# include<map>
# include<queue>
# include<cstring>
# include<algorithm>
using namespace std; # define LL long long
# define REP(i,s,n) for(int i=s;i<n;++i)
# define CL(a,b) memset(a,b,sizeof(a))
# define CLL(a,b,n) fill(a,a+n,b) const double inf=1e30;
const int INF=1<<30;
const int N=1000; struct Edge
{
int fr,to,cap,fw;
Edge(int _fr,int _to,int _cap,int _fw):fr(_fr),to(_to),cap(_cap),fw(_fw){}
};
vector<Edge>edges;
vector<int>G[N];
int W[N],L[N],n,cur[N],vis[N],d[N];
int a[30][30],s,t,ans[30]; void addEdge(int u,int v,int cap)
{
edges.push_back(Edge(u,v,cap,0));
edges.push_back(Edge(v,u,0,0));
int m=edges.size();
G[u].push_back(m-2);
G[v].push_back(m-1);
} void read()
{
scanf("%d",&n);
REP(i,0,n) scanf("%d%d",W+i,L+i);
REP(i,0,n) REP(j,0,n) scanf("%d",&a[i][j]);
} void init()
{
s=0,t=n*n+n+1;
edges.clear();
REP(i,0,t+1) G[i].clear();
} bool BFS()
{
CL(vis,0);
queue<int>q;
vis[s]=1;
d[s]=0;
q.push(s);
while(!q.empty()){
int u=q.front();
q.pop();
REP(i,0,G[u].size()){
Edge &e=edges[G[u][i]];
if(!vis[e.to]&&e.cap>e.fw){
vis[e.to]=1;
d[e.to]=d[u]+1;
q.push(e.to);
}
}
}
return vis[t];
} int DFS(int u,int a)
{
if(u==t||a==0) return a;
int flow=0,f;
for(int &i=cur[u];i<G[u].size();++i){
Edge &e=edges[G[u][i]];
if(d[e.to]==d[u]+1&&(f=DFS(e.to,min(a,e.cap-e.fw)))>0){
e.fw+=f;
edges[G[u][i]^1].fw-=f;
flow+=f;
a-=f;
if(a==0) break;
}
}
return flow;
} int Dinic()
{
int flow=0;
while(BFS()){
CL(cur,0);
flow+=DFS(s,INF);
}
return flow;
} void solve()
{
ans[0]=0;
REP(k,0,n){
int total=W[k];
REP(i,0,n) total+=a[k][i];
int flag=0;
REP(i,0,n) if(W[i]>total){
flag=1;
break;
}
if(flag) continue;
init();
int full=0;
REP(i,0,n){
REP(j,i+1,n){
full+=a[i][j];
if(a[i][j]>0) addEdge(s,i*n+j+1,a[i][j]);
addEdge(i*n+j+1,n*n+i+1,INF);
addEdge(i*n+j+1,n*n+j+1,INF);
}
if(W[i]<total) addEdge(n*n+i+1,t,total-W[i]);
}
int flow=Dinic();
if(flow==full) ans[++ans[0]]=k+1;
}
REP(i,1,ans[0]+1) printf("%d%c",ans[i],(i==ans[0])?'\n':' ');
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
read();
solve();
}
  return 0;
}

  

UVALive-2531 The K-League (最大流建模+枚举)的更多相关文章

  1. 【Uvalive 2531】 The K-League (最大流-类似公平分配问题)

    [题意] 有n个队伍进行比赛,每场比赛,恰好有一支队伍取胜.一支队伍败.每个队伍需要打的比赛场数相同,给你每个队伍目前已经赢得场数和输得场数,再给你一个矩阵,第 i 行第 j 列 表示队伍 i 和队伍 ...

  2. 【 UVALive - 5095】Transportation(费用流)

    Description There are N cities, and M directed roads connecting them. Now you want to transport K un ...

  3. UVaLive 2531 The K-League (网络流)

    题意:有 n 个队伍进行比赛,每个队伍比赛数目是一样的,每场恰好一个胜一个负,给定每个队伍当前胜的场数败的数目,以及两个队伍剩下的比赛场数,问你冠军队伍可能是哪些队. 析:对每个队伍 i 进行判断是不 ...

  4. POJ - 2516 Minimum Cost 每次要跑K次费用流

    传送门:poj.org/problem?id=2516 题意: 有m个仓库,n个买家,k个商品,每个仓库运送不同商品到不同买家的路费是不同的.问为了满足不同买家的订单的最小的花费. 思路: 设立一个源 ...

  5. poj-2516.minimum cost(k次费用流)

    Minimum Cost Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 19883   Accepted: 7055 Des ...

  6. UVaLive 4597 Inspection (网络流,最小流)

    题意:给出一张有向图,每次你可以从图中的任意一点出发,经过若干条边后停止,然后问你最少走几次可以将图中的每条边都走过至少一次,并且要输出方案,这个转化为网络流的话,就相当于 求一个最小流,并且存在下界 ...

  7. UVA11082 Matrix Decompressing 最大流建模解矩阵,经典

    /** 题目:UVA11082 Matrix Decompressing 链接:https://vjudge.net/problem/UVA-11082 题意:lrj入门经典P374 已知一个矩阵的行 ...

  8. POJ3498最大流,枚举终点,企鹅,基础最大流

    题意:       有一n个冰块,每个冰块上都有一些企鹅,所有的企鹅要跳到一个冰块上去,但是由于起跳是的后坐力原因导致每个冰块最多条mi次,最后问你所有的企鹅都跳到一个冰块上去的那块冰块可以是哪一块, ...

  9. POJ3189二分最大流(枚举下界,二分宽度,最大流判断可行性)

    题意:       有n头猪,m个猪圈,每个猪圈都有一定的容量(就是最多能装多少只猪),然后每只猪对每个猪圈的喜好度不同(就是所有猪圈在每个猪心中都有一个排名),然后要求所有的猪都进猪圈,但是要求所有 ...

随机推荐

  1. Oracle下回滚rollback的使用

    oracle中可以设置一个回滚点进行回滚 设置回滚名称 savepoint pointa ; 进行回滚 rollback to pointa; 如果期间有删除的数据就回来了

  2. poj1039 Pipe【计算几何】

    含[求直线交点].[判断直线与线段相交]模板   Pipe Time Limit: 1000MS   Memory Limit: 10000K Total Submissions:11940   Ac ...

  3. spring boot tomcat 线程数 修改初始线程数 统计性能 每百次请求耗时

    [root@f java]# tail -30 nohup.outsearchES-TimeMillisSpent:448P->1602@fT->http-nio-8080-exec-3t ...

  4. Mercurial

    Contributing Changes http://nginx.org/en/docs/contributing_changes.html Mercurial is used to store s ...

  5. scrapy爬虫系列之五--CrawlSpider的使用

    功能点:CrawlSpider的基本使用 爬取网站:保监会 主要代码: cf.py # -*- coding: utf-8 -*- import scrapy from scrapy.linkextr ...

  6. Redis主从切换

    案例 易车网:http://www.greatops.net/?id=232 redis主从切换:http://www.cnblogs.com/itdragon/p/7932178.htmlhttps ...

  7. leetcode之Maximal Square

    Given a 2D binary matrix filled with 0's and 1's, find the largest square containing all 1's and ret ...

  8. mysql 数据操作 单表查询 having 过滤

    SELECT 字段1,字段2... FROM 库名.表名 WHERE 条件 GROUP BY field HAVING 筛选 ORDER BY field LIMIT 限制条数 1.首先找到表 库.表 ...

  9. oracle基于3种方法的大数据量插入更新

    过程插入更新的3种方法: a.逐条检查插入或更新,同时执行插入或更新 b.逐条merge into(逐条是为了记录过程日志与错误信息) c.基于关联数组的检查插入.更新,通过forall批量sql执行 ...

  10. Openstack架构简介(一)

    1.1.1openstack介绍: openstack是(infrastructure as a service,基础设置即服务)IAAS架构的实现,OpenStack是一个由NASA(美国国家航空航 ...