题目大意:有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. poj1821 Fence【队列优化线性DP】

    Fence Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 6122   Accepted: 1972 Description ...

  2. 使用colmap进行稠密重建

    colmap应该是目前state-of-art的增量式SFM方案,可以方便的对一系列二维图片进行三维重建 不用对摄像机进行标定,只需要从不同角度对重建场景或物体进行拍摄得到一系列图像作为输入 首先需要 ...

  3. Use of ‘const’ in Functions Return Values

    Use of 'Const' in Function Return Values 为什么要在函数的返回值类型中添加Const? 1.Features Of the possible combinati ...

  4. 一致性hash 大众点评订单分库分表实践

    井底之蛙 https://mp.weixin.qq.com/s?src=3&timestamp=1543228894&ver=1&signature=uF6nV0yYseJ55 ...

  5. talib 中文文档(三):talib 方法大全

    Function API Examples Similar to TA-Lib, the function interface provides a lightweight wrapper of th ...

  6. Python开发【模块】:Urllib(一)

    Urllib模块 1.模块说明: Urllib库是Python中的一个功能强大.用于操作的URL,并在做爬虫的时候经常要用到的库.在Python2.X中,分Urllib库和Urllib库,Python ...

  7. LockSupport HotSpot里park/unpark的实现

    每个java线程都有一个Parker实例,Parker类是这样定义的: class Parker : public os::PlatformParker { private: volatile int ...

  8. [sql] 同库表(结构)的备份和sql聚合&navicat使用

    同库表的备份-赋值表结构和数据SQL语句 参考 有时候我们处理某个表时,需要先备份下这个表到当前这个库,然后再执行sql. 站在sql角度,就无需在mysqldump或者诸如导出sql的方式来备份了. ...

  9. java多线程(六)

    使用Runnable接口创建线程 Runnable接口 只有一个run()方法 Thread类实现了Runable接口 便于多个线程共享资源 Java不支持多继承,如果已经继承了某个基类,便要实现Ru ...

  10. monkey基础学习

    原文地址https://blog.csdn.net/beyond_f/article/details/78543070 一.Monkey测试简介 Monkey测试是Android平台自动化测试的一种手 ...