• BZOJ 1066: [SCOI2007]蜥蜴( 最大流 )


    结点容量..拆点然后随便写 

    ---------------------------------------------------------------

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
     
    using namespace std;
     
    #define chk(x, y) (x >= 0 && x < R && y >= 0 && y < C)
     
    const int maxn = 10000;
    const int maxm = 2900;
     
    int h[maxn], cnt[maxn];
    int X[maxm][maxm], Y[maxm][maxm];
    int R, C, D, V, S, T, N;
    char s[maxm];
     
    struct edge {
    int to, cap;
    edge *next, *rev;
    } E[1000000], *pt = E, *head[maxn], *p[maxn], *cur[maxn];
     
    inline void Add(int u, int v, int w) {
    pt->to = v; pt->cap = w; pt->next = head[u]; head[u] = pt++;
    }
     
    inline void AddEdge(int u, int v, int w) {
    Add(u, v, w); Add(v, u, 0);
    head[u]->rev = head[v];
    head[v]->rev = head[u];
    }
     
    void Init() {
    V = N = 0;
    scanf("%d%d%d", &R, &C, &D);
    memset(X, -1, sizeof X);
    for(int i = 0; i < R; i++) {
    scanf("%s", s);
    for(int j = 0; j < C; j++) if(s[j] > '0') {
    X[i][j] = V++;
    Y[i][j] = V++;
    AddEdge(X[i][j], Y[i][j], s[j] - '0');
    }
    }
    S = V++; T = V++;
    for(int i = 0; i < R; i++)
    for(int j = 0; j < C; j++) if(~X[i][j])
    for(int d = 1; d <= D; d++)
    for(int k = 0; k <= d; k++) {
    int x = i + k, y = j + d - k;
    if(chk(x, y) && ~X[x][y]) AddEdge(Y[i][j], X[x][y], maxn);
    x = i - k, y = j - d + k;
    if(chk(x, y) && ~X[x][y]) AddEdge(Y[i][j], X[x][y], maxn);
    x = i + k, y = j - d + k;
    if(chk(x, y) && ~X[x][y]) AddEdge(Y[i][j], X[x][y], maxn);
    x = i - k, y = j + d - k;
    if(chk(x, y) && ~X[x][y]) AddEdge(Y[i][j], X[x][y], maxn);
    }
    for(int i = 0; i < R; i++) {
    scanf("%s", s);
    for(int j = 0; j < C; j++) {
    if(~X[i][j] && (i < D || j < D || i + D >= R || j + D >= C)) AddEdge(Y[i][j], T, maxn);
    if(s[j] != '.') AddEdge(S, X[i][j], 1), N++;
    }
    }
    }
     
    void Solve() {
    memset(cnt, 0, sizeof cnt);
    memset(h, 0, sizeof h);
    cnt[0] = V;
    for(int i = 0; i < V; i++) cur[i] = head[i];
    int Flow = 0; edge* e;
    for(int x = S, A = maxn; h[S] < V; ) {
    for(e = cur[x]; e; e = e->next)
    if(h[e->to] + 1 == h[x] && e->cap) break;
    if(e) {
    p[e->to] = cur[x] = e;
    A = min(A, e->cap);
    if((x = e->to) == T) {
    for(; x != S; x = p[x]->rev->to) {
    p[x]->cap -= A;
    p[x]->rev->cap += A;
    }
    Flow += A;
    A = maxn;
    }
    } else {
    if(!--cnt[h[x]]) break;
    h[x] = V;
    for(e = head[x]; e; e = e->next) if(h[e->to] + 1 < h[x] && e->cap) {
    h[x] = h[e->to] + 1;
    cur[x] = e;
    }
    cnt[h[x]]++;
    if(x != S) x = p[x]->rev->to;
    }
    }
    printf("%d ", N - Flow);
    }
     
    int main() {
    Init();
    Solve();
    return 0;
    }

    ---------------------------------------------------------------

    1066: [SCOI2007]蜥蜴

    Time Limit: 1 Sec  Memory Limit: 162 MB
    Submit: 2516  Solved: 1240
    [Submit][Status][Discuss]

    Description

    在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外。 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到平面距离不超过d的任何一个石柱上。石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减1(如果仍然落在地图内部,则到达的石柱高度不变),如果该石柱原来高度为1,则蜥蜴离开后消失。以后其他蜥蜴不能落脚。任何时刻不能有两只蜥蜴在同一个石柱上。

    Input

    输入第一行为三个整数r,c,d,即地图的规模与最大跳跃距离。以下r行为石竹的初始状态,0表示没有石柱,1~3表示石柱的初始高度。以下r行为蜥蜴位置,“L”表示蜥蜴,“.”表示没有蜥蜴。

    Output

    输出仅一行,包含一个整数,即无法逃离的蜥蜴总数的最小值。

    Sample Input

    5 8 2
    00000000
    02000000
    00321100
    02000000
    00000000
    ........
    ........
    ..LLLL..
    ........
    ........

    Sample Output

    1

    HINT

    100%的数据满足:1<=r, c<=20, 1<=d<=4

    Source

  • 相关阅读:
    Nginx中如何配置中文域名?
    VS2012找不到EF框架实体模型的解决方法
    来自一位家长的电话
    孩子大了真是不好管了
    springboot项目不加端口号也可以访问项目的方法
    分享几个上机案例题
    今晚在学校值班……
    3班的第二次模拟面试
    Sword 09
    Sword 06
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/5038712.html
Copyright © 2020-2023  润新知