zoukankan      html  css  js  c++  java
  • HDU 3338 Kakuro Extension(网络流)

    因为某个地方m写成n玄学调bug一个小时...

    写完内心是崩溃的...

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include <list>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #define N 40010
    #define inf 1000000000
    using namespace std;
    class Graphic{
    public:
        friend void show();
        void init(int a,int b){
            src = a,dst = b;
            if(dst >= N)for(;;);
            for(int i = 0 ; i <= dst ; ++i)G[i].clear();
            edge.clear();
            cnt = 0;
        }
        void add(int u,int v,int cap){
            _add(u,v,cap);
            _add(v,u,0);
        }
        int Dinic(){
            int ans = 0;
            while (bfs()) {
                memset(cur, 0, sizeof(cur));
                ans+=dfs(src,inf);
            }
            return ans;
        }
    private:
        bool bfs(){
            while (!que.empty())que.pop();
            que.push(src);
            memset(dis,-1, sizeof(dis));
            dis[src] = 0;
            while(!que.empty()){
                int u = que.front();
                que.pop();
                for(int i = 0 ; i < G[u].size() ; ++i){
                    int v = edge[G[u][i]].to;
                    if(edge[G[u][i]].cap and dis[v]==-1){
                        dis[v] = dis[u]+1;
                        que.push(v);
                    }
                }
            }
            return dis[dst]!=-1;
        }
        int dfs(int u,int a){
            if(u==dst or a == 0)return a;
            int ret = 0,f;
            for(int &i = cur[u] ; i < G[u].size() ; ++i){
                int v = edge[G[u][i]].to;
                int tmp = edge[G[u][i]].cap;
                if(dis[v] == dis[u] + 1 and tmp > 0 and (f = dfs(v,min(a,tmp)))>0){
                    ret+=f;
                    edge[G[u][i]].cap-=f;
                    edge[G[u][i]^1].cap+=f;
                    a-=f;
                    if(a==0)break;
                }
            }
            return ret;
        }
    private:
        int src,dst,dis[N],cur[N];
        int cnt;
        struct Edge{
            int to,cap;
            Edge(int a,int b):to(a),cap(b){}
        };
        queue<int>que;
        vector<int>G[N];
        vector<Edge>edge;
        void _add(int u,int v,int d){
            edge.emplace_back(Edge(v,d));
            G[u].push_back(cnt++);
        }
    };
    Graphic ss;
    char str[105][105][10];
    int down_right[105][105][2],n,m;
    int get_dat(char *s){
        int ans = 0;
        while (*s and isdigit(*s)){
            ans = ans*10+*s-'0';
            ++s;
        }
        return ans;
    }
    int id[105][105],tol;
    void deal(int i,int j){
        int cnt;
        down_right[i][j][0] = isdigit(str[i][j][0])?get_dat(str[i][j]):-1;
        down_right[i][j][1] = isdigit(str[i][j][4])?get_dat(str[i][j]+4):-1;
        if(isdigit(str[i][j][0])){
            cnt = 0;
            for(int k = i+1 ; k <= n and str[k][j][0]=='.' ; ++k){
                ++cnt;
            }
            down_right[i][j][0]-=cnt;
        }
        if(isdigit(str[i][j][4])){
            cnt = 0;
            for(int k = j+1 ; k <= m and str[i][k][0]=='.' ; ++k){
                ++cnt;
            }
            down_right[i][j][1]-=cnt;
        }
        if(isdigit(str[i][j][0])or isdigit(str[i][j][4])){
            id[i][j]=++tol;
            ++tol;
        }
    }
    int res[105][105];
    void show(){
        for(int i = 1 ; i <= n ; ++i){
            for(int j = 1 ; j <= m/**因为这里笔者调了一个小时....**/ ; ++j){
                if(down_right[i][j][1]!=-1){
                    for(int k = 1 ; str[i][j+k][0]=='.' and k < ss.G[id[i][j]+1].size() ; ++k){
                       /// cerr<<ss.edge[ss.G[id[i][j]+1][k]].to<<" "<<id[i][j]+1<<endl;
                        res[i][j+k] = 9 - ss.edge[ss.G[id[i][j]+1][k]].cap;
                    }
                }
            }
        }
        for(int i = 1 ; i <= n ; ++i){
            for(int j = 1 ; j <= m ; ++j){
                if(str[i][j][0]=='.'){
                    printf("%d",res[i][j]);
                    ///if(res[i][j]==0x3f3f3f3f)for(;;);
                }
                else putchar('_');
                putchar(j==m?'
    ':' ');
            }
            puts("");
        }
    }
    int main(){
        while(cin>>n>>m){
            for(int i = 1 ; i <= n ; ++i){
                for(int j = 1 ; j <= m ; ++j){
                    scanf("%s",str[i][j]);
                }
            }
            int num = 0;
            tol = 0;
            for(int i = 1 ; i <= n ; ++i){
                for(int j = 1 ; j <= m ; ++j){
                    deal(i,j);
                }
            }
            int src = 0,dst = tol+1;
            ss.init(src,dst);
            for(int i = 1 ; i <= n ; ++i){
                for(int j = 1 ; j <= m ; ++j){
                    if(down_right[i][j][1]!=-1){
                    ///    cerr<<i<<" "<<j<<":";
                        ss.add(src,id[i][j]+1,down_right[i][j][1]);
                        for(int k = j+1 ; k <= m and str[i][k][0]=='.' ; ++k){
                            int to = i-1;
                            for( ; to > 1 and str[to][k][0]=='.'; --to);
                            if(down_right[to][k][0]==-1)for(;;);
                            ss.add(id[i][j]+1,id[to][k],8);
                        }
                    }
                    if(down_right[i][j][0]!=-1){
                        ss.add(id[i][j],dst,down_right[i][j][0]);
                    }
                }
            }
            ss.Dinic();
            show();
        }
    }
    
    
    /**
    2 4
    xxxxxxx 002/xxx xxxxxxx 002/xxx
    xxx/002 ....... xxx/002 .......
     */

    一个模板可以用一年..

    从题目抽象出网络流的概念,从源点向横向格子建边,横向格子向对应竖向建边,竖向格子向汇点建边,跑网络流无脑找出流量即可。

  • 相关阅读:
    【40讲系列1】数组、链表
    更改凭证类型
    将公司代码设置给生产性的(不能删除业务数据的配置)
    使用参考过账
    查看凭证行项目
    查看凭证过账行项目
    预制凭证
    做凭证时凭证日期等于过账日期
    英语-20210302
    自动计算税额
  • 原文地址:https://www.cnblogs.com/DevilInChina/p/9451558.html
Copyright © 2011-2022 走看看