zoukankan      html  css  js  c++  java
  • 【最大流】【HDU3338】【Kakuro Extension】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3338

    题目大意:填数字,使白色区域的值得和等于有值得黑色区域的相对应的值,用网络流来做

    题目思路:增加一个源点和汇点,然后左进上出,用源点连左面,容量为相对应的值,汇点连上面,容量是相对应的值,然后左面连空白区域的,容量为8,因为数字为1-9,有下限,但因每个空白必须有值,所以至少为一,所以容量空间为0-8;然后空白区域来连上面,容量同样为8;


    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    #define INF 999999999
    #define maxn 14000
    
    #define RE(x) (x)^1
    int head[maxn];
    int st,ed;//开始节点,结束节点
    struct Edge
    {
        int v,next;
        int val;
        Edge() {}
        Edge( int V , int NEXT , int W = 0 ):v(V),next(NEXT),val(W) {}
    } edge[500000];
    int lvl[maxn], gap[maxn];
    int cnt_edge;
    int map[maxn][maxn];
    struct gg
    {
        int x,y;
        int val;
    } row[maxn],col[maxn];
    int emp,row_num,col_num;
    int n,m,T;
    void Insert_Edge( int u , int v , int flow = 0 )
    {
    
        edge[cnt_edge] = Edge(v,head[u],flow);
        head[u] = cnt_edge++;
        edge[cnt_edge] = Edge(u,head[v]);
        head[v] = cnt_edge++;
    
    }
    void Init()
    {
        cnt_edge = 0;
        memset(head,-1,sizeof(head));
        memset(lvl, 0, sizeof (lvl));
        memset(gap, 0, sizeof (gap));
    }
    int dfs(int u, int flow)
    {
        if (u==ed)
        {
            return flow;
        }
        int tf = 0, sf, mlvl = ed-1;
        for (int i= head[u]; i != -1; i = edge[i].next)
        {
            if (edge[i].val > 0)
            {
                if (lvl[u] ==lvl[edge[i].v]+1)
                {
                    sf = dfs(edge[i].v, min(flow-tf, edge[i].val));
                    edge[i].val -= sf;
                    edge[RE(i)].val += sf;
                    tf += sf;
                    if (lvl[st] >=ed)
                    {
                        return tf;
                    }
                    if (tf == flow)
                    {
                        break;
                    }
                }
                mlvl = min(mlvl, lvl[edge[i].v]);
            }
        }
        if (tf == 0)
        {
            --gap[lvl[u]];
            if (!gap[lvl[u]])
            {
                lvl[st] =ed;
            }
            else
            {
                lvl[u] = mlvl+1;
                ++gap[lvl[u]];
            }
        }
        return tf;
    }
    int sap()
    {
        int ans = 0;
        gap[0]=ed;
        while (lvl[st] <ed)
        {
            ans += dfs(st, INF);
        }
        return ans;
    }
    int print( int tp )
    {
        int ans = 0;
        int id = tp + row_num+1;
        for( int i = head[id] ; i != -1 ; i = edge[i].next )
        {
            int v = edge[i].v;
            if( v <=row_num+1 )
            {
                ans+= edge[i].val;
                break;
            }
        }
        return ans+1;
    }
    int main()
    {
        int i,j;
        char s[15];
        //freopen("F://ACMInput/input.txt","r",stdin);
        while(scanf("%d%d",&n,&m)!=-1)
        {
            emp=row_num=col_num=0;
            for(i=0; i<n; i++)
                for(j=0; j<m; j++)
                {
                    scanf("%s",s);
                    if(s[0]=='.')
                    {
                        map[i][j]=++emp;
                    }
                    else
                    {
                        map[i][j]=-1;
                        if(s[4]!='X')
                        {
                            int tp=(s[4]-'0')*100+(s[5]-'0')*10+s[6]-'0';
                            row[++row_num].x=i;
                            row[row_num].y=j;
                            row[row_num].val=tp;
                        }
                        if(s[0]!= 'X' )
                        {
                            int tp = (s[0]-'0')*100+(s[1]-'0')*10+s[2]-'0';
                            col[++col_num].x = i;
                            col[col_num].y = j;
                            col[col_num].val = tp;
                        }
                    }
                }
            T=emp+col_num+row_num+2;
            st=1;
            ed=T;
            Init();
            for(i=1; i<=row_num; i++)
            {
                int pos = i;
                int x = row[i].x;
                int y = row[i].y;
                int cnt_len = 0;
                for( y=y+1; y <m ; y++ )
                {
                    if( map[x][y] != -1 )
                    {
                        cnt_len++;
                        Insert_Edge(i+1, row_num+ map[x][y]+1,8);
                    }
                    else break;
                }
                Insert_Edge(st,pos+1,row[i].val-cnt_len);
            }
    
            for( i = 1 ; i <=col_num ; i++ )
            {
                int pos =i+1+row_num+emp;
                int x = col[i].x;
                int y = col[i].y;
                int cnt_len = 0;
                for( x=x+1 ; x < n ; x++ )
                {
                    if( map[x][y] != -1 )
                    {
                        cnt_len++;
                        Insert_Edge(row_num+ map[x][y]+1,pos,8);
    
                    }
                    else break;
                }
                Insert_Edge(pos,ed,col[i].val-cnt_len);
            }
            sap();
            for(i=0; i<n; i++)
            {
                for(j=0; j<m; j++)
                {
    
                    if(map[i][j]==-1)
                        printf("_ ");
                    else
                        printf("%d ",print(map[i][j]));
                }
                printf("
    ");
            }
        }
        return 0;
    }
    


  • 相关阅读:
    夯实Java基础系列23:一文读懂继承、封装、多态的底层实现原理
    夯实Java基础系列22:一文读懂Java序列化和反序列化
    夯实Java基础系列21:Java8新特性终极指南
    夯实Java基础系列20:从IDE的实现原理聊起,谈谈那些年我们用过的Java命令
    FireDAC的SQLite初探
    delphi7 TRichView 安装
    Delphi7 GDI+学习
    Delphi7画好看的箭头线
    python swap
    pycharm **教程 大家快激活吧
  • 原文地址:https://www.cnblogs.com/zy691357966/p/5480347.html
Copyright © 2011-2022 走看看