zoukankan      html  css  js  c++  java
  • HDU 4888 Redraw Beautiful Drawings

    http://acm.hdu.edu.cn/showproblem.php?pid=4888

    题意:给行数N和列数M,颜色数K,以及每一行的和,每一列的和。问有没有唯一排列方法。

    题解:网络流,建模一直是个大问题……根本建不出……看完题解后恍然大悟……

       建图:源点到每一行建边,容量为此行之和;每一行和每一列建边,容量为K;每一列和汇点建边,容量为此列之和。

       判断是否有解:源点出发的边和到达汇点的  边是否满流。

       判断唯一解:残余网络是否有长度大于二的环。(有多条路可选,不影响总流量)(DFS)

             唯一解的结果:G[i][j]的流量。

    第一次存边表……当做模板好了……实在是太弱了……

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <cstdlib>
      5 #include <cmath>
      6 #include <string>
      7 #include <vector>
      8 #include <list>
      9 #include <map>
     10 #include <queue>
     11 #include <stack>
     12 #include <bitset>
     13 #include <algorithm>
     14 #include <numeric>
     15 #include <functional>
     16 #include <set>
     17 #include <fstream>
     18 
     19 using namespace std;
     20 
     21 const int INF=0xfffffff;
     22 const int maxe=410*410*10;
     23 const int maxn=410+410;
     24 
     25 struct edge{
     26     int to,cap,next;
     27     edge(int to=0,int cap=0,int next=0):to(to),cap(cap),next(next){}
     28 }G[maxe];
     29 int head[maxn],level[maxn],nedge;
     30 bool used[maxn];
     31 int g[maxn][maxn];
     32 int sumr,sumc;
     33 int N,M,K;
     34 int flag;
     35 
     36 void add_edge(int from,int to,int cap)
     37 {
     38     G[++nedge]=edge(to,cap,head[from]);
     39     head[from]=nedge;
     40     G[++nedge]=edge(from,0,head[to]);
     41     head[to]=nedge;
     42 }
     43 
     44 bool bfs(int S,int T)
     45 {
     46     memset(level,0xff,sizeof(level));
     47     level[S]=0;
     48     queue<int>q;
     49     q.push(S);
     50     while(!q.empty())
     51     {
     52         int v=q.front();q.pop();
     53         for(int k=head[v];k!=-1;k=G[k].next)
     54         {
     55             edge e=G[k];
     56             if(level[e.to]==-1&&e.cap)
     57             {
     58                 level[e.to]=level[v]+1;
     59                 q.push(e.to);
     60             }
     61         }
     62     }
     63     return level[T]!=-1;
     64 }
     65 
     66 int dfs(int v,int f,int T)
     67 {
     68     if(v==T||f==0) return f;
     69     int flow=0;
     70     for(int k=head[v];k!=-1;k=G[k].next)
     71     {
     72         edge & e=G[k];
     73         if(level[e.to]==level[v]+1)
     74         {
     75             int d;
     76             if((d=dfs(e.to,min(f,e.cap),T))>0)
     77             {
     78                 G[k].cap-=d;
     79                 G[k^1].cap+=d;
     80                 flow+=d;
     81                 f-=d;
     82                 if(f==0) return flow;
     83             }
     84         }
     85     }
     86     level[v]=-1;
     87     return flow;
     88 }
     89 
     90 int max_flow(int s,int t)
     91 {
     92     int flow=0;
     93     int f;
     94     while (bfs(s,t)==1)
     95     {
     96         while((f=dfs(s,INF,t))>0)
     97         {
     98             flow+=f;
     99             //printf("%d
    ",flow);
    100         }
    101     }
    102     return flow;
    103 }
    104 
    105 int dfs_loop(int u,int rev)
    106 {
    107     for(int k=head[u];k!=-1;k=G[k].next)
    108     {
    109         if(k==(rev^1)) continue;
    110         if(G[k].cap)
    111         {
    112             if(used[G[k].to]) return 1;
    113             used[G[k].to]=true;
    114             if(dfs_loop(G[k].to,k)==1) return 1;
    115             used[G[k].to]=false;
    116         }
    117     }
    118     return 0;
    119 }
    120 
    121 int judge_loop()
    122 {
    123     for(int i=1;i<=N;i++)
    124     {
    125         if(dfs_loop(i,-1))
    126         {
    127             return 0;
    128         }
    129     }
    130     return 1;
    131 }
    132 
    133 void put()
    134 {
    135     for(int u=1;u<=N;u++)
    136     {
    137         for(int k=head[u];k!=-1;k=G[k].next)
    138         {
    139             int v=G[k].to;
    140             if(v>N&&v<=N+M) g[u][v-N]=K-G[k].cap;
    141         }
    142     }
    143     for(int i=1;i<=N;i++)
    144     {
    145         for(int j=1;j<=M;j++)
    146         {
    147             if(j>1) printf(" ");
    148             printf("%d",g[i][j]);
    149         }
    150         puts("");
    151     }
    152 }
    153 
    154 void init()
    155 {
    156     memset(head,0xff,sizeof(head));
    157     memset(g,0,sizeof(g));
    158     memset(used,0,sizeof(used));
    159     nedge=-1;
    160     sumr=0;
    161     sumc=0;
    162     flag=0;
    163 }
    164 
    165 int main()
    166 {
    167    // freopen("/Users/apple/Desktop/暑假/contest 3 B/contest 3 B/in","r",stdin);
    168     while(scanf("%d%d%d",&N,&M,&K)!=EOF)
    169     {
    170         init();
    171         int s=0;
    172         int t=N+M+1;
    173         int cap;
    174         for(int i=1;i<=N;i++)
    175         {
    176             scanf("%d",&cap);
    177             sumr+=cap;
    178             add_edge(s, i, cap);//s到行之和 s-(1~N)
    179             for(int j=1;j<=M;j++)
    180             {
    181                 add_edge(i,N+j,K);//(1~N)-(N+1~N+M)
    182             }
    183         }
    184         for(int i=1;i<=M;i++)
    185         {
    186             scanf("%d",&cap);
    187             sumc+=cap;
    188             add_edge(N+i,t,cap);//(N+1~N+M)-t
    189         }
    190         int flow1=max_flow(s, t);
    191         if(sumr!=sumc) puts("Impossible");
    192         else if(flow1!=sumr) puts("Impossible");
    193         else if(!judge_loop()) puts("Not Unique");
    194         else{
    195             puts("Unique");
    196             put();
    197         }
    198     }
    199     return 0;
    200 }

  • 相关阅读:
    动态规划——Best Time to Buy and Sell Stock IV
    动态规划——Split Array Largest Sum
    动态规划——Burst Ballons
    动态规划——Best Time to Buy and Sell Stock III
    动态规划——Edit Distance
    动态规划——Longest Valid Parentheses
    动态规划——Valid Permutations for DI Sequence
    构建之法阅读笔记05
    构建之法阅读笔记04
    构建之法阅读笔记03
  • 原文地址:https://www.cnblogs.com/der-z/p/3877910.html
Copyright © 2011-2022 走看看