zoukankan      html  css  js  c++  java
  • HDU 3338 Kakuro Extension

    Kakuro Extension

    题意:现在有一个n*m的矩形,现在每个白色的点都可以填 [1, 9] 中的一个数字。现在要求每行加起来的值等于左边的那个黑块的右值,每列加起来等于上边那个黑块的左值,求合法方案数。

    题解:因为每个点至少是1,如果直接建边跑最大流的话会导致某些点的值为0,现在要保证每个点至少为1,我们可以直接把 s 流向每个白点流量为1, 然后黑点流入白点的流量减少边数的流量,最后跑最大流,输出答案。

    代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
      4 #define LL long long
      5 #define ULL unsigned LL
      6 #define fi first
      7 #define se second
      8 #define pb emplace_back
      9 #define lson l,m,rt<<1
     10 #define rson m+1,r,rt<<1|1
     11 #define lch(x) tr[x].son[0]
     12 #define rch(x) tr[x].son[1]
     13 #define max3(a,b,c) max(a,max(b,c))
     14 #define min3(a,b,c) min(a,min(b,c))
     15 typedef pair<int,int> pll;
     16 const int inf = 0x3f3f3f3f;
     17 const LL INF = 0x3f3f3f3f3f3f3f3f;
     18 const LL mod =  (int)1e9+7;
     19 const int N = 100*101 * 2;
     20 const int M = N * 20;
     21 int ans[150][150];
     22 int val[150][150][2];
     23 int head[N], deep[N], cur[N];
     24 int w[M], to[M], nx[M];
     25 int tot;
     26 void add(int u, int v, int val){
     27     w[tot]  = val; to[tot] = v;
     28     nx[tot] = head[u]; head[u] = tot++;
     29 
     30     w[tot] = 0; to[tot] = u;
     31     nx[tot] = head[v]; head[v] = tot++;
     32 }
     33 int bfs(int s, int t){
     34     queue<int> q;
     35     memset(deep, 0, sizeof(deep));
     36     q.push(s);
     37     deep[s] = 1;
     38     while(!q.empty()){
     39         int u = q.front();
     40         q.pop();
     41         for(int i = head[u]; ~i; i = nx[i]){
     42             if(w[i] > 0 && deep[to[i]] == 0){
     43                 deep[to[i]] = deep[u] + 1;
     44                 q.push(to[i]);
     45             }
     46         }
     47     }
     48     return deep[t] > 0;
     49 }
     50 int Dfs(int u, int t, int flow){
     51     if(u == t) return flow;
     52     for(int &i = cur[u]; ~i; i = nx[i]){
     53         if(deep[u]+1 == deep[to[i]] && w[i] > 0){
     54             int di = Dfs(to[i], t, min(w[i], flow));
     55             if(di > 0){
     56                 w[i] -= di, w[i^1] += di;
     57                 return di;
     58             }
     59         }
     60     }
     61     return 0;
     62 }
     63 
     64 int Dinic(int s, int t){
     65     int ans = 0, tmp;
     66     while(bfs(s, t)){
     67         for(int i = 0; i <= t; i++) cur[i] = head[i];
     68         while(tmp = Dfs(s, t, inf)) ans += tmp;
     69     }
     70     return ans;
     71 }
     72 void init(){
     73     memset(head, -1, sizeof(head));
     74     tot = 0;
     75 }
     76 char str[N];
     77 int n, m;
     78 #define id(i,j) (i-1)*m+j
     79 void GG(){
     80     for(int i = 1; i <= n; i++)
     81         for(int j = 1; j <= m; j++){
     82             if(val[i][j][1] > 0){
     83                 for(int z = head[id(i,j)]; ~z; z = nx[z]){
     84                     if(z&1);
     85                     else {
     86                         int tx = to[z] / m + 1, ty = to[z] % m;
     87                         if(!ty) ty = m, tx -= 1;
     88                         ans[tx][ty] = 9 - w[z] + 1;
     89                     }
     90                 }
     91             }
     92         }
     93 }
     94 
     95 int main(){
     96     ///Fopen;
     97     while(~scanf("%d%d", &n, &m)){
     98        init(); for(int i = 1; i <= n; i++)
     99             for(int j = 1; j <= m; j++){
    100                 ans[i][j] = 0;
    101                 scanf("%s", str+1);
    102                 if(str[1] == '.') val[i][j][0] = val[i][j][1] = -2;
    103                 else {
    104                     if(str[1] == 'X') val[i][j][0] = -1; /// down
    105                     else val[i][j][0] = (str[1]-'0')*100 + (str[2]-'0')*10 + str[3] - '0';
    106                     if(str[5] == 'X') val[i][j][1] = -1;
    107                     else val[i][j][1] = (str[5]-'0')*100 + (str[6]-'0')*10 + str[7] - '0';
    108                 }
    109             }
    110         int s = 0, t = n*m*2+1;
    111         for(int i = 1; i <= n; i++){
    112             for(int j = 1; j <= m; j++){
    113                 if(val[i][j][1] > 0){
    114                     int tmp = val[i][j][1];
    115                     int z = j+1;
    116                     while(z <= m && val[i][z][0] == -2){
    117                         add(id(i,j), id(i,z), 9);
    118                         add(s, id(i,z), 1);
    119                        // cout << i << ' ' << j << "  link   " << i << ' ' << z << endl;
    120                         z++;
    121                         tmp--;
    122                     }
    123                     add(s, id(i,j), tmp);
    124                     j = z - 1;
    125                 }
    126             }
    127         }
    128         for(int j = 1; j <= m; j++)
    129             for(int i = 1; i <= n; i++){
    130                 if(val[i][j][0] > 0){
    131                     int z = i + 1;
    132                     add(id(i,j)+n*m, t, val[i][j][0]);
    133                     while(z <= n && val[z][j][0] == -2){
    134                         add(id(z,j),id(i,j)+n*m,9);
    135                         z++;
    136                     }
    137                     i = z - 1;
    138                 }
    139         }
    140         //puts("Oh mather fuck!!!");
    141          int tt = Dinic(s,t);
    142          //cout << tt << endl;
    143         GG();
    144         for(int i = 1; i <= n; i++){
    145             for(int j = 1; j <= m; j++){
    146                 if(ans[i][j]) printf("%d", ans[i][j]);
    147                 else printf("_");
    148                 if(j!=m) printf(" ");
    149             }
    150             puts("");
    151         }
    152     }
    153     return 0;
    154 }
    155 /*
    156 2 2
    157 XXXXXXX 009/XXX
    158 XXX/009 .......
    159 */
    View Code
  • 相关阅读:
    数学+高精度 ZOJ 2313 Chinese Girls' Amusement
    最短路(Bellman_Ford) POJ 1860 Currency Exchange
    贪心 Gym 100502E Opening Ceremony
    概率 Gym 100502D Dice Game
    判断 Gym 100502K Train Passengers
    BFS POJ 3278 Catch That Cow
    DFS POJ 2362 Square
    DFS ZOJ 1002/HDOJ 1045 Fire Net
    组合数学(全排列)+DFS CSU 1563 Lexicography
    stack UVA 442 Matrix Chain Multiplication
  • 原文地址:https://www.cnblogs.com/MingSD/p/9738766.html
Copyright © 2011-2022 走看看