• Kakuro Extension【最大流】


    HDU-3338

      这道题真的处理起来好复杂啊,题意就是个简单的方格填数问题,但是每个白点至少放1,那么最后的可能解是怎样的呢?我们是不是要把x轴上的和y轴上的统一起来,然后就是每个点都被对应的x和y匹配起来,那么,之后,用每个点的x向y建立边,跑最大流,每个点的放的值就是反向边的权值了。

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <string>
    #include <cstring>
    #include <algorithm>
    #include <limits>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <set>
    #include <map>
    #define lowbit(x) ( x&(-x) )
    #define pi 3.141592653589793
    #define e 2.718281828459045
    #define INF 0x3f3f3f3f
    #define HalF (l + r)>>1
    #define lsn rt<<1
    #define rsn rt<<1|1
    #define Lson lsn, l, mid
    #define Rson rsn, mid+1, r
    #define QL Lson, ql, qr
    #define QR Rson, ql, qr
    #define myself rt, l, r
    #define MP(x, y) make_pair(x, y)
    using namespace std;
    typedef unsigned long long ull;
    typedef long long ll;
    const int maxN = 1e2 + 7, maxE = 1e5 + 7, st = 0;
    pair<int, int> re_xy[20007];
    int N, M, head[20007], cur[20007], cnt, ed, id[maxN][maxN], tot, ou[maxN][maxN];
    char mp[maxN][maxN][10];
    int down[maxN][maxN], righ[maxN][maxN];
    struct Eddge
    {
        int nex, to, flow;
        Eddge(int a=-1, int b=0, int c=0):nex(a), to(b), flow(c) {}
    }edge[maxE];
    inline void addEddge(int u, int v, int w)
    {
        edge[cnt] = Eddge(head[u], v, w);
        head[u] = cnt++;
    }
    inline void _add(int u, int v, int w) { addEddge(u, v, w); addEddge(v, u, 0); }
    inline void solve(int x, int y)
    {
        if(mp[x][y][1] == 'X' && mp[x][y][7] == 'X') { id[x][y] = -1; return; }
        if(mp[x][y][1] == '.') { return; }
        re_xy[++tot] = MP(x, y);
        id[x][y] = tot;
        down[x][y] = righ[x][y] = 0;
        if(mp[x][y][1] != 'X') for(int i=1; i<=3; i++) down[x][y] = down[x][y] * 10 + mp[x][y][i] - '0';
        if(mp[x][y][5] != 'X') for(int i=5; i<=7; i++) righ[x][y] = righ[x][y] * 10 + mp[x][y][i] - '0';
    }
    int deep[20007];
    queue<int> Q;
    inline bool bfs()
    {
        for(int i=0; i<=ed; i++) deep[i] = 0;
        deep[st] = 1;
        while(!Q.empty()) Q.pop();
        Q.push(st);
        while(!Q.empty())
        {
            int u = Q.front(); Q.pop();
            for(int i=head[u], v, f; ~i; i=edge[i].nex)
            {
                v = edge[i].to; f = edge[i].flow;
                if(f && !deep[v])
                {
                    deep[v] = deep[u] + 1;
                    Q.push(v);
                }
            }
        }
        return deep[ed];
    }
    int  dfs(int u, int Dist)
    {
        if(u == ed) return Dist;
        for(int &i=cur[u], v, f; ~i; i=edge[i].nex)
        {
            v = edge[i].to; f = edge[i].flow;
            if(f && deep[v] == deep[u] + 1)
            {
                int di = dfs(v, min(Dist, f));
                if(di)
                {
                    edge[i].flow -= di;
                    edge[i^1].flow += di;
                    return di;
                }
            }
        }
        return 0;
    }
    inline int Dinic()
    {
        int ans = 0, tmp;
        while(bfs())
        {
            for(int i=0; i<=ed; i++) cur[i] = head[i];
            while((tmp = dfs(st, INF))) ans += tmp;
        }
        return ans;
    }
    inline void init()
    {
        cnt = tot = 0;
        memset(head, -1, sizeof(head));
        memset(id, 0, sizeof(id));
    }
    int main()
    {
        while(scanf("%d%d", &N, &M) != EOF)
        {
            init();
            for(int i=1; i<=N; i++)
            {
                for(int j=1; j<=M; j++)
                {
                    scanf("%s", mp[i][j] + 1);
                    solve(i, j);
                }
            }
            ed = (tot << 1) + 1;
            for(int i=1, le_id=0, up_id=0; i<=N; i++)
            {
                for(int j=1; j<=M; j++)
                {
                    if(mp[i][j][1] == '.')
                    {
                        for(int dx = i - 1; dx > 0; dx--)
                        {
                            if(id[dx][j])
                            {
                                up_id = dx;
                                down[dx][j]--;
                                break;
                            }
                        }
                        for(int dy = j - 1; dy > 0; dy--)
                        {
                            if(id[i][dy])
                            {
                                le_id = dy;
                                righ[i][dy]--;
                                break;
                            }
                        }
                        _add(id[i][le_id], id[up_id][j] + tot, 8);
                    }
                }
            }
            for(int i=1; i<=N; i++)
            {
                for(int j=1; j<=M; j++)
                {
                    if(id[i][j] > 0)
                    {
                        if(mp[i][j][1] != 'X') _add(id[i][j] + tot, ed, down[i][j]);
                        if(mp[i][j][5] != 'X') _add(st, id[i][j], righ[i][j]);
                    }
                }
            }
            Dinic();
            for(int x = 1; x <= tot; x++)
            {
                for(int i=head[x], y, f; ~i; i=edge[i].nex)
                {
                    y = edge[i].to; f = edge[i^1].flow;
                    if(y == st) continue;
                    ou[re_xy[x].first][re_xy[y - tot].second] = f;
                }
            }
            for(int i=1; i<=N; i++)
            {
                for(int j=1; j<=M; j++)
                {
                    if(mp[i][j][1] != '.') printf("_");
                    else printf("%d", ou[i][j] + 1);
                    printf("%c", j == M ? '
    ' : ' ');
                }
            }
        }
        return 0;
    }
    /*
    3 3
    XXXXXXX 009/XXX XXXXXXX
    XXX/009 ....... XXXXXXX
    XXXXXXX XXXXXXX XXXXXXX
    */

     

  • 相关阅读:
    一起talk C栗子吧(第九十回:C语言实例--使用管道进行进程间通信三)
    集群技术(三)MySQL集群深度解析
    ZOJ 3609 Modular Inverse(扩展欧几里德)
    8,16小感
    Dagger2----一个最简单的Dagger2依赖的实现
    android:模拟水波效果的自己定义View
    SQL Server 运行计划操作符具体解释(1)——断言(Assert)
    参数类型 (实体类层)eneity或pojo 常用参数类型
    参数类型 (@Controller层)
    参数类型 (@Service层) impl
  • 原文地址:https://www.cnblogs.com/WuliWuliiii/p/11266490.html
Copyright © 2020-2023  润新知