• URAL 1774 Barber of the Army of Mages 最大流


    思路:

      以理发的次数当容量,源点到每个人建一条容量为2的边,人到他可达的每个时间点建一条边,每个时间点到汇点建一条容量为m的边。然后判断最大流是否等于2*n。

    代码:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cstdlib>
      5 #include <cmath>
      6 #include <algorithm>
      7 #include <string>
      8 #include <queue>
      9 #include <stack>
     10 #include <vector>
     11 #include <map>
     12 #include <set>
     13 #include <functional>
     14 #include <time.h>
     15 
     16 using namespace std;
     17 
     18 
     19 using namespace std;
     20 
     21 const int INF = 1<<30;
     22 const int MAXN = 3000;
     23 const int MAXE = (int)5e5+10;
     24 
     25 struct Dinic{
     26     struct Edge {
     27         int from, to, cap, flow;
     28         //从from到to的容量为cap,流量为flow的弧
     29     };
     30 
     31     int n, m, s, t; //结点数,边数(包括反向弧),源点,汇点
     32     vector<Edge> edges; //边表。 edges[e]和edges[e^1]互为反向弧
     33     vector<int> G[MAXN]; //邻接表,G[i][j]表示结点i的第j条边在e数组中的序号
     34     bool vis[MAXN]; //bfs使用
     35     int d[MAXN]; //从起点到i的距离
     36     int cur[MAXN]; //当前弧下标
     37 
     38     inline void init() {
     39         edges.clear();
     40         for (int i = 0; i <= n; i++) {
     41             G[i].clear();
     42         }
     43     }
     44 
     45     inline void addEdge(int from, int to, int cap) {
     46         edges.push_back((Edge){from, to, cap, 0});
     47         edges.push_back((Edge){to, from, 0, 0});
     48         m = edges.size();
     49         G[from].push_back(m-2);
     50         G[to].push_back(m-1);
     51     }
     52 
     53     bool bfs() {
     54         memset(vis, false, sizeof(vis));
     55         queue<int> q;
     56         q.push(s);
     57         d[s] = 0;
     58         vis[s] = true;
     59 
     60         while (!q.empty()) {
     61             int u = q.front(); q.pop();
     62             for (int i = 0; i < G[u].size(); i++) {
     63                 Edge &e = edges[G[u][i]];
     64                 if (!vis[e.to] && (e.cap > e.flow)) { //只考虑残量网络中的弧
     65                     vis[e.to] = true;
     66                     d[e.to] = d[u]+1;
     67                     q.push(e.to);
     68                 }
     69             }
     70         }
     71         return vis[t];
     72     }
     73 
     74     int dfs(int u, int c) {
     75         if (u==t || 0==c) return c;
     76         int flow = 0, f;
     77         for (int &i = cur[u]; i < G[u].size(); i++) { //从上次考虑的弧
     78             Edge &e = edges[G[u][i]];
     79             if ((d[u]+1)==d[e.to] && (f = dfs(e.to, min(c, e.cap-e.flow))) > 0) {
     80                 e.flow += f;
     81                 edges[G[u][i]^1].flow -= f;
     82                 flow += f;
     83                 c -= f;
     84                 if (0==c) break;
     85             }
     86         }
     87         return flow;
     88     }
     89 
     90     int MaxFlow(int s, int t) {
     91         this->s = s; this->t = t;
     92         int flow = 0;
     93         while (bfs()) {
     94             memset(cur, 0, sizeof(cur));
     95             flow += dfs(s, INF);
     96         }
     97         return flow;
     98     }
     99     void print(int st, int ed) {
    100         for (int i = st; i < ed; i++) {
    101             bool flag = false;
    102             for (int j = 0; j < G[i].size(); j++) {
    103                 Edge &e = edges[G[i][j]];
    104                 if (e.flow==1) {
    105                     if (flag) printf(" ");
    106                     printf("%d", e.to);
    107                     if (flag) {
    108                         puts("");
    109                         break;
    110                     }
    111                     flag = true;
    112                 }
    113             }
    114         }
    115     }
    116 };
    117 
    118 Dinic a;
    119 int n, m;
    120 
    121 void solve() {
    122     // 时间点: 0~2000
    123     // 人: 2001~2000+n
    124     //s: 0, t: 2001+n
    125     int s = 2001+n;
    126     int t = s+1;
    127     a.n = t;
    128     a.init();
    129     int x, y;
    130     int Max = 0;
    131     for (int i = 0; i < n; i++)
    132         a.addEdge(s, 2001+i, 2);
    133 
    134     for (int i = 0; i < n; i++) {
    135         scanf("%d%d", &x, &y);
    136         Max = max(Max, x+y);
    137         for (int j = 0; j < y; j++) {
    138             a.addEdge(2001+i, x+j, 1);
    139         }
    140     }
    141     for (int i = 0; i <= Max; i++)
    142         a.addEdge(i, t, m);
    143     int ans = a.MaxFlow(s, t);
    144     if (2*n==ans) {
    145         puts("Yes");
    146         a.print(2001, 2001+n);
    147     } else
    148         puts("No");
    149 }
    150 
    151 int main() {
    152     #ifdef Phantom01
    153         freopen("A.txt", "r", stdin);
    154     #endif // Phantom01
    155 
    156     while (scanf("%d%d", &n, &m)!=EOF) {
    157         solve();
    158     }
    159 
    160     return 0;
    161 }
    View Code

    其实做这个题,是为了检验更学的新模板 Dinic

  • 相关阅读:
    CUDA C Best Practices Guide 在线教程学习笔记 Part 1
    0_Simple__simpleCallback
    0_Simple__simpleAtomicIntrinsics + 0_Simple__simpleAtomicIntrinsics_nvrtc
    0_Simple__simpleAssert + 0_Simple__simpleAssert_nvrtc
    0_Simple__matrixMulDrv
    0_Simple__matrixMulCUBLAS
    0_Simple__matrixMul + 0_Simple__matrixMul_nvrtc
    0_Simple__inlinePTX + 0_Simple__inlinePTX_nvrtc
    0_Simple__fp16ScalarProduct
    0_Simple__cudaOpenMP
  • 原文地址:https://www.cnblogs.com/Phantom01/p/3704425.html
Copyright © 2020-2023  润新知