LA 2531 The K-league 最大流

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <fstream>
  4 #include <algorithm>
  5 #include <cmath>
  6 #include <deque>
  7 #include <vector>
  8 #include <queue>
  9 #include <string>
 10 #include <cstring>
 11 #include <map>
 12 #include <stack>
 13 #include <set>
 14 #define INF 0x3f3f3f3f
 15 #define OPEN_FILE
 16 #define MAXN 626
 17 using namespace std;
 18
 19 int n;
 20 int win[MAXN], remain[MAXN][MAXN];
 21 struct Edge{
 22     int from, to, cap, flow;
 23     //Edge(int u, int v, int c, int f) :from(u), to(v), cap(c), flow(f){};
 24 };
 25 bool comp(const Edge& a, const Edge& b){
 26     return (a.from < b.from || (a.from == b.from && a.to < b.to));
 27 }
 28 struct Dinic{
 29     int n, m, i, s, t;
 30     Edge e;
 31     vector<Edge> edges;
 32     vector<int> G[MAXN];
 33     int d[MAXN], cur[MAXN];
 34     bool vis[MAXN];
 35     void init(int n){
 36         this->n = n;
 37         for (i = 0; i <= n; i++){
 38             G[i].clear();
 39         }
 40         edges.clear();
 41     }
 42     void AddEdge(int from, int to, int cap){
 43         edges.push_back(Edge{ from, to, cap, 0 });
 44         edges.push_back(Edge{ to, from, 0, 0 });
 45         m = edges.size();
 46         G[from].push_back(m - 2);
 47         G[to].push_back(m - 1);
 48     }
 49     bool BFS(){
 50         memset(vis, 0, sizeof(vis));
 51         queue<int> Q;
 52         Q.push(s);
 53         d[s] = 0;
 54         vis[s] = 1;
 55         while (!Q.empty()){
 56             int x = Q.front();
 57             Q.pop();
 58             for (i = 0; i < G[x].size(); i++){
 59                 Edge& e = edges[G[x][i]];
 60                 if (!vis[e.to] && e.cap > e.flow){
 61                     vis[e.to] = true;
 62                     d[e.to] = d[x] + 1;
 63                     Q.push(e.to);
 64                 }
 65             }
 66         }
 67         return vis[t];
 68     }
 69     int DFS(int x, int a){
 70         if (x == t || a == 0) return a;
 71         int flow = 0, f;
 72         for (int& i = cur[x]; i < G[x].size(); i++){
 73             Edge& e = edges[G[x][i]];
 74             if (d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow))) > 0){
 75                 e.flow += f;
 76                 edges[G[x][i] ^ 1].flow -= f;
 77                 flow += f;
 78                 a -= f;
 79                 if (a == 0) break;
 80             }
 81         }
 82         return flow;
 83     }
 84     int MaxFlow(int s, int t, int need){
 85         int flow = 0;
 86         this->s = s;
 87         this->t = t;
 88         while (BFS()){
 89             memset(cur, 0, sizeof(cur));
 90             flow += DFS(s, INF);
 91             if (flow > need) return flow;
 92         }
 93         return flow;
 94     }
 95     bool checkFull(int s){
 96         for (int i = 0; i < G[s].size(); i++){
 97             if (edges[G[s][i]].flow != edges[G[s][i]].cap){
 98                 return false;
 99             }
100         }
101         return  true;
102     }
103 };
104
105 int main()
106 {
107 #ifdef OPEN_FILE
108     freopen("in.txt", "r", stdin);
109     freopen("out.txt", "w", stdout);
110 #endif // OPEN_FILE
111     int T, x;
112     scanf("%d", &T);
113     for (int cas = 1; cas <= T; cas++){
114         scanf("%d", &n);
115         memset(win, 0, sizeof(win));
116         for (int i = 1; i <= n; i++){
117             scanf("%d%d", &win[i], &x);
118         }
119         memset(remain, 0, sizeof(remain));
120         int p = 0;
121         for (int i = 1; i <= n; i++){
122             for (int j = 1; j <= n; j++){
123                 scanf("%d", &x);
124                 if (i == j) continue;
125                 remain[i][0] += x;
126                 if (remain[i][j] == 0 && remain[j][i] == 0){
127                     remain[i][j] = x;
128                     ++p;
129                 }
130             }
131         }
132         int s = 0, t = n + p + 1, q;
133         bool flag, first;
134         Dinic ex;
135         first = false;
136         for (int k = 1; k <= n; k++){
137             ex.init(n * n);
138             flag = false;
139             q = 1;
140             int total = win[k] + remain[k][0];
141             for (int i = 1; i <= n; i++){
142                 for (int j = i + 1; j <= n; j++){
143                     if (!remain[i][j]) continue;
144                     ex.AddEdge(s, q, remain[i][j]);
145                     ex.AddEdge(q, p + i, INF);
146                     ex.AddEdge(q, p + j, INF);
147                     q++;
148                 }
149                 if (total - win[i] < 0) {
150                     flag = true;
151                     break;
152                 }
153                 ex.AddEdge(p + i, t, total - win[i]);
154             }
155             if (flag){
156                 continue;
157             }
158             ex.MaxFlow(s, t, INF);
159             if (ex.checkFull(0)){
160                 if (first){
161                     printf(" ");
162                 }
163                 printf("%d", k);
164                 first = true;
165             }
166         }
167         printf("\n");
168     }
169 }
时间: 2024-10-12 15:29:23

LA 2531 The K-league 最大流的相关文章

(算法竞赛入门经典 优先队列)LA 3135(前K条指令)

A data stream is a real-time, continuous, ordered sequence of items. Some examples include sensor data, Internet traffic, financial tickers, on-line auctions, and transaction logs such as Web usage logs and telephone call records. Likewise, queries o

(算法入门经典大赛 优先级队列)LA 3135(之前K说明)

A data stream is a real-time, continuous, ordered sequence of items. Some examples include sensor data, Internet traffic, financial tickers, on-line auctions, and transaction logs such as Web usage logs and telephone call records. Likewise, queries o

hdu4106 区间k覆盖问题(连续m个数,最多选k个数) 最小费用最大流 建图巧妙

/** 题目:hdu4106 区间k覆盖问题(连续m个数,最多选k个数) 最小费用最大流 建图巧妙 链接:http://acm.hdu.edu.cn/showproblem.php?pid=4106 题意:给你n个数,每连续m个数,最多选k个数,问可以选的数的权值和最大多少. 思路:可以转化为区间k覆盖问题.区间k覆盖问题是每个点最多被k个区间覆盖.本题是每个区间最多选k个点. 刚好相反.我的做法有点不同其他博客那种做法.当然本质一样. 我这里的i就是原来n个数的下标,现在作为图中该数的节点编号

BZOJ 2324 营救皮卡丘(最小费用最大流)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2324 题意:n+1个城市(0到n).初始时K个 人都在0城市.城市之间有距离.要求(1)遍历完n个城市(有一个人遍历了某个城市就算这个城市被遍历了):(2)遍历i城市前必须遍历完前i-1个城 市,并且在遍历前i-1个城市时不能经过大于等于i的城市.在满足(1)(2)的前提下使得K个人走的总距离最小. 思路:我们先看在实际情况下可以怎么走. (1)某个人遍历完某个城市后停在那里,以后不再

poj 2526 Minimum Cost【最小费用最大流】

题目链接:http://poj.org/problem?id=2516 题意: n个店主 m个供应商 k种货物 给你店主对k种货物的需求及供货商k种货物的囤货量及K种运输费用. 解法:k次费用流,分别求每种货物的费用.源点到供应点建边,店主到汇点建边,费用均为0,容量为1.然后供应点到店主建边,费用为矩阵,容量无穷大即可. 代码: /* POJ 2195 Going Home 邻接矩阵形式最小费用最大流 */ #include<stdio.h> #include<iostream>

POJ 2516 Minimum Cost 【费用流】

建模比较难想.. #include<iostream> #include<deque> #include<vector> #include<cstring> #include<cmath> #define INF 2e9 using namespace std; int T,ans; struct edge{ int v,cap,reverse,cost; }; vector<int> edges[1005];//邻接表 vector

多源多汇费用流——poj2516

网络流的题好难..感觉有点遭不住了 这题用矩阵存图,然后把k个物品,每个物品都求一次费用流 /* 多源多汇的费用流 其实是k个费用流 */ #include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define maxn 205 struct Edge{int to,nxt,w,c;}e[maxn<<2]; int head[maxn],tot,n,m,s,t; void init(){} void a

HDU-3081 Marriage Match II (最大流,二分答案,并查集)

题目链接:HDU-3081 Marriage Match II 题意 有$n$个男孩和$n$个女孩玩配对游戏,每个女孩有一个可选男孩集合(即每轮游戏的搭档可从集合中选择),已知有些女孩之间是朋友(这里的朋友关系是相互的,即a和b是朋友,a和c是朋友,那么b和c也是朋友),那么她们可以共享男孩集合,即这些男孩集合的并集成为她们各自的可选男孩集合,如果某一轮女孩选择了一个男孩作为搭档,则这个男孩后面不能再作为这个女孩的搭档,问游戏最多进行几轮. 思路 女孩朋友之间共享男孩集合问题可以用并查集解决,将

luogu P2604 [ZJOI2010]网络扩容 |费用流

题目描述 给定一张有向图,每条边都有一个容量\(C\)和一个扩容费用\(W\).这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不扩容的情况下,1到N的最大流: 2. 将1到N的最大流增加K所需的最小扩容费用. 输入格式 输入文件的第一行包含三个整数\(N,M,K\),表示有向图的点数.边数以及所需要增加的流量. 接下来的M行每行包含四个整数\(u,v,C,W\),表示一条从u到v,容量为C,扩容费用为W的边. 输出格式 输出文件一行包含两个整数,分别表示问题1和问题2的答案. 利用残余网