zoukankan      html  css  js  c++  java
  • CF 152E Garden

    CF_152E

        这个题目只需要求一棵斯坦纳树,但是蛋疼的是需要打印路径,因此要多开一个数组记录路径。一种还算比较省事的记录路径的办法就是如果是spfa拓展出来的状态就用负数记录一下拓展的方向,如果是子树组合出来的状态就用正数记录一下其中一棵子树的点集状态,这样能很方便的求出另一棵子树的点集状态。

    #include<stdio.h>
    #include<string.h>
    #define MAXN 110
    #define ST 138
    #define MAXQ 256010
    #define INF 0x3f3f3f3f
    const int Q = 256000;
    int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};
    int N, M, K, a[MAXN][MAXN];
    int bit[MAXN][MAXN], f[MAXN][MAXN][ST], pre[MAXN][MAXN][ST], vis[MAXN][MAXN];
    struct point
    {
        int x, y, st;
        point(){}
        point(int _x, int _y, int _st) : x(_x), y(_y), st(_st){}
    }q[MAXQ];
    int front, rear, inq[MAXN][MAXN][ST];
    void init()
    {
        int i, j, n = 0, x, y;
        for(i = 1; i <= N; i ++)
            for(j = 1; j <= M; j ++)
                scanf("%d", &a[i][j]);
        for(i = 1; i <= N; i ++)
            for(j = 1; j <= M; j ++)
                bit[i][j] = 0, memset(f[i][j], 0x3f, sizeof(f[i][j])), memset(pre[i][j], 0x3f, sizeof(pre[i][j]));
        for(i = 0; i < K; i ++)
        {
            scanf("%d%d", &x, &y);
            bit[x][y] = 1 << (n ++), f[x][y][bit[x][y]] = a[x][y];
        }
    }
    int can(int x, int y)
    {
        return x >= 1 && x <= N && y >= 1 && y <= M;
    }
    void spfa()
    {
        int i, x, y, st, nx, ny, nst;
        while(front != rear)
        {
            x = q[front].x, y = q[front].y, st = q[front].st, inq[x][y][st] = 0;
            ++ front > Q ? front = 0 : 0;
            for(i = 0; i < 4; i ++)
            {
                nx = dx[i] + x, ny = dy[i] + y, nst = st | bit[nx][ny];
                if(can(nx, ny) && f[x][y][st] + a[nx][ny] < f[nx][ny][nst])
                {
                    f[nx][ny][nst] = f[x][y][st] + a[nx][ny], pre[nx][ny][nst] = -i;
                    q[rear ++] = point(nx, ny, nst), inq[nx][ny][nst] = 1;
                    rear > Q ? rear = 0 : 0;
                }
            }    
        }
    }
    void dfs(int x, int y, int st)
    {
        vis[x][y] = 1;
        if(pre[x][y][st] == INF)
            return ;
        if(pre[x][y][st] <= 0)
            dfs(x - dx[-pre[x][y][st]], y - dy[-pre[x][y][st]], st - bit[x][y]);
        else
            dfs(x, y, pre[x][y][st]), dfs(x, y, st - pre[x][y][st] | bit[x][y]);
    }
    void solve()
    {
        int i, j, k, x, y, st, nn = 1 << K, ans;
        front = rear = 0;
        for(i = 1; i <= N; i ++)    
            for(j = 1; j <= M; j ++)
                memset(inq[i][j], 0, sizeof(inq[i][j])), vis[i][j] = 0;
        for(i = 0; i < nn; i ++)
        {
            for(j = 1; j <= N; j ++)
                for(k = 1; k <= M; k ++)
                {
                    for(st = i & i - 1; st; st = st - 1 & i)
                    {
                        int temp = f[j][k][st | bit[j][k]] + f[j][k][i - st | bit[j][k]] - a[j][k];
                        if(temp < f[j][k][i])
                            f[j][k][i] = temp, pre[j][k][i] = st | bit[j][k];
                    }
                    if(f[j][k][i] < INF)
                    {
                        q[rear ++] = point(j, k, i), inq[j][k][i] = 1;
                        rear > Q ? rear = 0 : 0;
                    }
                }
            spfa();
        }
        
        ans = INF;
        for(i = 1; i <= N; i ++)
            for(j = 1; j <= M; j ++)
                if(f[i][j][nn - 1] < ans)
                    ans = f[i][j][nn - 1], x = i, y = j;
        dfs(x, y, nn - 1);
        printf("%d\n", ans);
        for(i = 1; i <= N; i ++)
        {
            for(j = 1; j <= M; j ++)
                printf("%c", vis[i][j] ? 'X' : '.');
            printf("\n");
        }
    }
    int main()
    {
        while(scanf("%d%d%d", &N, &M, &K) == 3)
        {
            init();
            solve();    
        }
        return 0;    
    }
  • 相关阅读:
    Luogu P3703 [SDOI2017]树点涂色
    好吧,又建了一个博客
    JDI tutorial (trace example)
    【译文】Java Logging
    openjdk 完全编译指南
    入门: 使用JNI 从C++代码中调用Java的静态方法
    使用JVMTI创建调试和监控代理
    【译文】 GC 安全点 和安全区域
    Java虚拟机 safepoints 初探
    NoClassDefFoundError vs ClassNotFoundException
  • 原文地址:https://www.cnblogs.com/staginner/p/2621463.html
Copyright © 2011-2022 走看看