• HDU 1733 Escape


    HDU_1733

        分层图网络流。为了保证每秒钟每个地方只站一个人,可以把每个点i拆成i和i'并连一条容量为一的边。分层图中每一层都表示一秒钟的站位情况,然后不断地增加图的层数,直到最大流等于人数为止就可以得到最小的时间了。

        至于-1的情况可以一开始用搜索预处理出来。

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define MAXN 20
    #define MAXD 60010
    #define MAXM 420010
    #define INF 0x3f3f3f3f
    int N, M, first[MAXD], e, next[MAXM], v[MAXM], flow[MAXM], cnt;
    int S, T, d[MAXD], q[MAXD], work[MAXD], vis[MAXN][MAXN], NUM;
    int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};
    char b[MAXN][MAXN];
    void add(int x, int y, int z)
    {
        v[e] = y, flow[e] = z;
        next[e] = first[x], first[x] = e ++;
    }
    int inside(int x, int y)
    {
        return x >= 1 && x <= N && y >= 1 && y <= M;
    }
    void init()
    {
        int i, j, x;
        for(i = 1; i <= N; i ++) scanf("%s", b[i] + 1);
        S = 0, T = 1;
        memset(first, -1, sizeof(first)), e = 0;
        for(i = 1; i <= N; i ++)
            for(j = 1; j <= M; j ++)
                if(b[i][j] == 'X')
                {
                    x = N * M + i * M + j;
                    add(S, x, 1), add(x, S, 0);
                }
    }
    void DFS(int x, int y)
    {
        int i, nx, ny;
        vis[x][y] = 1;
        for(i = 0; i < 4; i ++)
        {
            nx = x + dx[i], ny = y + dy[i];
            if(inside(nx, ny) && b[nx][ny] != '#' && !vis[nx][ny]) DFS(nx, ny);
        }
    }
    void build(int cur)
    {
        int i, j, k, ni, nj, d = 2 * N * M * cur, x, y;
        for(i = 1; i <= N; i ++)
            for(j = 1; j <= M; j ++)
                if(b[i][j] != '#')
                {
                    x = d + i * M + j, y = x + N * M;
                    add(x, y, 1), add(y, x, 0);
                    if(b[i][j] == '@') add(y, T, 1), add(T, y, 0);
                    y = x - N * M;
                    add(y, x, 1), add(x, y, 0);
                    for(k = 0; k < 4; k ++)
                    {
                        ni = i + dx[k], nj = j + dy[k];
                        if(inside(ni, nj) && b[ni][nj] != '#')
                        {
                            x = d - N * M + i * M + j, y = d + ni * M + nj;
                            add(x, y, 1), add(y, x, 0);
                        }
                    }
                }
    }
    int bfs()
    {
        int i, j, rear = 0;
        memset(d, -1, sizeof(d[0]) * cnt);
        d[S] = 0, q[rear ++] = S;
        for(i = 0; i < rear; i ++)
            for(j = first[q[i]]; j != -1; j = next[j])
                if(flow[j] && d[v[j]] == -1)
                {
                    d[v[j]] = d[q[i]] + 1, q[rear ++] = v[j];
                    if(v[j] == T) return 1;
                }
        return 0;
    }
    int dfs(int cur, int a)
    {
        if(cur == T) return a;
        for(int &i = work[cur]; i != -1; i = next[i])
            if(flow[i] && d[v[i]] == d[cur] + 1)
                if(int t = dfs(v[i], std::min(a, flow[i])))
                {
                    flow[i] -= t, flow[i ^ 1] += t;
                    return t;
                }
        return 0;
    }
    int dinic()
    {
        int ans = 0, t;
        while(bfs())
        {
            memcpy(work, first, sizeof(first[0]) * cnt);
            while(t = dfs(S, INF)) ans += t;
        }
        return ans;
    }
    void solve()
    {
        int i, j, ans;
        memset(vis, 0, sizeof(vis));
        NUM = 0;
        for(i = 1; i <= N; i ++)
            for(j = 1; j <= M; j ++)
            {
                if(b[i][j] == '@' && !vis[i][j])
                    DFS(i, j);
                if(b[i][j] == 'X') ++ NUM;
            }
        for(i = 1; i <= N; i ++)
            for(j = 1; j <= M; j ++)
                if(b[i][j] == 'X' && !vis[i][j])
                {
                    printf("-1\n");
                    return ;
                }
        if(NUM == 0)
        {
            printf("0\n");
            return ;
        }
        for(i = 1, ans = 0, cnt = N * M * 2 + M + 1;; i ++)
        {
            build(i);
            cnt += N * M * 2;
            ans += dinic();
            if(ans == NUM) break;
        }
        printf("%d\n", i);
    }
    int main()
    {
        while(scanf("%d%d", &N, &M) == 2)
        {
            init();
            solve();
        }
        return 0;
    }
  • 相关阅读:
    免费的视频、音频转文本
    Errors are values
    Codebase Refactoring (with help from Go)
    Golang中的坑二
    Cleaner, more elegant, and wrong(msdn blog)
    Cleaner, more elegant, and wrong(翻译)
    Cleaner, more elegant, and harder to recognize(翻译)
    vue控制父子组件渲染顺序
    computed 和 watch 组合使用,监听数据全局数据状态
    webstorm破解方法
  • 原文地址:https://www.cnblogs.com/staginner/p/2657870.html
Copyright © 2020-2023  润新知