LA 2531 The K-league 最大流

来源:互联网 发布:手机淘宝5.8.0 编辑:程序博客网 时间:2024/05/20 06:25
 

 

 

 

  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_FILE108     freopen("in.txt", "r", stdin);109     freopen("out.txt", "w", stdout);110 #endif // OPEN_FILE111     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 }

 

0 0