• BZOJ 1340: [Baltic2007]Escape逃跑问题


    1340: [Baltic2007]Escape逃跑问题

    Time Limit: 5 Sec  Memory Limit: 162 MB
    Submit: 285  Solved: 133
    [Submit][Status][Discuss]

    Description

    战犯们企图逃离监狱,他们详细地计划了如何逃出监狱本身,逃出监狱之后他们希望在附近的一个村子里找到掩护。村子(下图中的B)和监狱(图中的A)中间有一个峡谷,这个峡谷也是有士兵守卫的。守卫峡谷的士兵们坐在岗哨上很少走动,每个士兵的观察范围是100米。士兵所处位置决定了战犯们能否安全通过峡谷,安全通过的条件就是在任何时刻战犯们距离最近的士兵大于100米。 给定峡谷的长、宽和每个士兵在峡谷中的坐标,假定士兵的位置一直保持不变,请你写一个程序计算战犯们能否不被士兵发现,顺利通过峡谷。如果不能,那么战犯们最少需要消灭几个士兵才能安全通过峡谷(无论士兵是否被另一个士兵看到,他都可以被消灭)。 
     
     

    Input

    第一行有三个整数L、W和N,分别表示峡谷的长度、宽度和士兵的人数。接下来的N行,每行两个整数Xi和Yi,表示第i个士兵在峡谷的坐标(0 <= Xi <= L, 0 <= Yi <= W),坐标以米为单位,峡谷的西南角坐标为(0, 0),东北角坐标为(L, W),见上图。注意:通过峡谷可以从(0, ys)(0 <= ys <= W)到(L, ye)(0 <= ye <= W),其中ys, ye不一定是整数。

    Output

    只有一行,为一个整数,即安全通过峡谷需要消灭的士兵的人数,如果不需要消灭任何士兵,则输出0。

    Sample Input

    130 340 5
    10 50
    130 130
    70 170
    0 180
    60 260

    Sample Output

    1

    HINT

    1 <= W <= 50,000 1 <= L <= 50,000 1 <= N <= 250

    Source

     
    [Submit][Status][Discuss]

    网络流 最小割 

    暴力判断两个士兵是否相交就行

      1 #include <bits/stdc++.h>
      2 
      3 const int siz = 500005;
      4 const int inf = 1000000007;
      5 
      6 int L, W, N;
      7 
      8 int X[siz];
      9 int Y[siz];
     10 
     11 int S, T;
     12 
     13 int hd[siz];
     14 int nt[siz];
     15 int to[siz];
     16 int fl[siz];
     17 
     18 inline void add(int u, int v, int f)
     19 {
     20     static int edge = 0, init = 1;
     21     
     22     if (init)memset(hd, -1, sizeof(hd)), init = 0;
     23     
     24     nt[edge] = hd[u]; to[edge] = v; fl[edge] = f; hd[u] = edge++;
     25     nt[edge] = hd[v]; to[edge] = u; fl[edge] = 0; hd[v] = edge++;
     26 }
     27 
     28 int dep[siz];
     29 
     30 inline bool bfs(void)
     31 {
     32     static int que[siz], l, r;
     33     memset(dep, 0, sizeof(dep));
     34     dep[que[l = 0] = S] = r = 1;
     35     
     36     while (l != r)
     37     {
     38         int u = que[l++], v;
     39         
     40         for (int i = hd[u]; ~i; i = nt[i])
     41             if (fl[i] && !dep[v = to[i]])
     42                 dep[que[r++] = v] = dep[u] + 1;
     43     }
     44     
     45     return dep[T];
     46 }
     47 
     48 int cur[siz];
     49 
     50 int dfs(int u, int f)
     51 {
     52     using std::min;
     53     
     54     if (u == T || !f)
     55         return f;
     56     
     57     int used = 0, flow, v;
     58     
     59     for (int i = cur[u]; ~i; i = nt[i])
     60         if (fl[i] && dep[v = to[i]] == dep[u] + 1)
     61         {
     62             flow = dfs(v, min(fl[i], f - used));
     63             
     64             used += flow;
     65             fl[i] -= flow;
     66             fl[i^1] += flow;
     67             
     68             if (fl[i])
     69                 cur[u] = i;
     70             
     71             if (f == used)
     72                 return f;
     73         }
     74     
     75     if (!used)
     76         dep[u] = 0;
     77     
     78     return used;
     79 }
     80 
     81 inline int maxFlow(void)
     82 {
     83     int maxFlow = 0, newFlow;
     84     
     85     while (bfs())
     86     {
     87         memcpy(cur, hd, sizeof(cur));
     88         
     89         while (newFlow = dfs(S, inf))
     90             maxFlow += newFlow;
     91     }
     92     
     93     return maxFlow;
     94 }
     95 
     96 inline long long sqr(long long x)
     97 {
     98     return x * x;
     99 }
    100 
    101 inline long long dis(int i, int j)
    102 {
    103     return sqr(X[i] - X[j]) + sqr(Y[i] - Y[j]);
    104 }
    105 
    106 signed main(void)
    107 {
    108     scanf("%d%d%d", &L, &W, &N);
    109     
    110     for (int i = 1; i <= N; ++i)
    111         scanf("%d%d", X + i, Y + i);
    112         
    113     S = 0, T = 2 * N + 1;
    114     
    115     for (int i = 1; i <= N; ++i)
    116     {
    117         add(i, i + N, 1);
    118         if (Y[i] <= 100)add(S, i, inf);
    119         if (Y[i] >= W - 100)add(i + N, T, inf);
    120     }
    121     
    122     for (int i = 1; i <= N; ++i)
    123         for (int j = 1; j <= N; ++j)
    124             if (dis(i, j) <= 40000 && i != j)
    125                 add(i + N, j, inf);
    126     
    127     printf("%d
    ", maxFlow());
    128 }

    @Author: YouSiki

  • 相关阅读:
    pyqt的setObjectName()/findChild()
    pyqt的多Button的点击事件的槽函数的区分发送signal的按钮。
    分布式存储
    QTableWidget的表头颜色设置
    QListView的子项的ViewMode
    QHeaderView的点击和双击事件
    LeetCode(63):不同路径 II
    LeetCode(62):不同路径
    LeetCode(61):旋转链表
    LeetCode(60): 第k个排列
  • 原文地址:https://www.cnblogs.com/yousiki/p/6282498.html
Copyright © 2020-2023  润新知