题目大意:有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. python基础之迭代器协议和生成器

    迭代器和生成器补充:http://www.cnblogs.com/luchuangao/p/6847081.html 一 递归和迭代 略 二 什么是迭代器协议 1.迭代器协议是指:对象必须提供一个ne ...

  2. Python开发【笔记】:如何在字典遍历中删除key值?

    数据遍历时不能犯傻系列 前言: 针对字典做一些操作时,有时会遇到下面的状况,列如我们需要把data中的key值根据replace中的映射关系进行替换(Caller替换为caller) data = { ...

  3. Python开发【Django】:时间处理

    时间格式化 做博客后台时,需要经常对数据库里面的时间格式(2017-02-17 02:10:44.308638)进行处理,格式化成自己想要的时间(列如年月日),下面就来记录下如何对时间进行处理 1.时 ...

  4. mysql join实现方式

    1. nested loop join 分别从两个表读一行数据进行两两对比,复杂度是n^2 2. block nested loop join 分别从两个表读很多行数据,然后进行两两对比,复杂度也是n ...

  5. java-mybaits-00201-DAO-SqlSession使用范围

    1.SqlSession的使用范围 SqlSession中封装了对数据库的操作,如:查询.插入.更新.删除等. 通过SqlSessionFactory创建SqlSession,而SqlSessionF ...

  6. Mysql学习笔记—concat以及group_concat的用法(转载)

    本文中使用的例子均在下面的数据库表tt2下执行: 一.concat()函数 1.功能:将多个字符串连接成一个字符串. 2.语法:concat(str1, str2,...) 返回结果为连接参数产生的字 ...

  7. zlib编译安装

    从http://www.zlib.net/下载了最新的源代码 zlib提供了vs sln文件,在zlib-1.2.8\contrib\vstudio\目录有 其中的zlibstat是编译为静态库zli ...

  8. 分页组件vue和jsp版本

    vue版本 <template> <div class="com-vscroll"> <slot name="mcontent"& ...

  9. Educational Codeforces Round 54 (Rated for Div. 2) Solution

    A - Minimizing the String solved 题意:给出一个字符串,可以移掉最多一个字符,在所有可能性中选取一个字典序最小的. 思路:显然,一定可以移掉一个字符,如果移掉的字符的后 ...

  10. BabelMap 10.0.0.3 汉化版已经发布

    新的 BabelMap 在日前发布. 新版本增加了字符书签的管理功能,以及将窗口最小化到系统通知栏(时钟区域)的功能. 请点击主页左上角进入下载页面下载.