码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 3338 Kakuro Extension

时间:2018-10-03 21:55:48      阅读:181      评论:0      收藏:0      [点我收藏+]

标签:char   fopen   amp   img   最大   nic   size   head   second   

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

 

HDU 3338 Kakuro Extension

标签:char   fopen   amp   img   最大   nic   size   head   second   

原文地址:https://www.cnblogs.com/MingSD/p/9738766.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!