• HDU 3338 Kakuro Extension


    题意:看图就知道大概是个什么意思了,就是每行连续的数之和等于一个规定的数,每列连续的数之和等于一个规定的数。

               

    神题啊。。这都可以是网络流。。貌似也只能是网络流了。。直接搜的题解。。觉得建图也不是那么神奇  但是就是觉得真的不可思议。。

    首先,流量有下界,是1,那么干脆所有的边的流量都把这个1的部分减掉。

    直接贴这个博客上说的:http://www.cnblogs.com/ylfdrib/archive/2010/08/15/1799903.html

    建图:

    一共有四类点:

    1. 构造源点S,汇点T

    2. 有行和的格子,此类节点设为A

    3. 空白格,设为B

    4. 有列和的格子,设为C

    则可以建边:

    1. <S, A> 容量和行和

    2. <A, B> 容量为8

    3. <B, C> 容量为8

    4. <C, T> 容量为列和

    最后怎么去填格子里的数字呢?

    每个格子里的数字等于1+从行和中流向这个格子的流量和

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #define INF 0x7fffffff
      6 #define maxn 20010
      7 #define maxm 500000
      8 using namespace std;
      9 int v[maxm],next[maxm],w[maxm];
     10 int first[maxn],d[maxn],work[maxn],q[maxn];
     11 int e,S,T;
     12 int map[105][105];
     13 struct Row{
     14     int x,y,z;
     15 }row[maxn];
     16 struct Col{
     17     int x,y,z;
     18 }col[maxn];
     19 
     20 void init(){
     21     e = 0;
     22     memset(first,-1,sizeof(first));
     23 }
     24 
     25 void add_edge(int a,int b,int c){
     26     //printf("add:%d to %d,cap = %d
    ",a,b,c);
     27     v[e] = b;w[e] = c;next[e] = first[a];first[a] = e++;
     28     v[e] = a;w[e] = 0;next[e] = first[b];first[b] = e++;
     29 }
     30 
     31 int bfs(){
     32     int rear = 0;
     33     memset(d,-1,sizeof(d));
     34     d[S] = 0;q[rear++] = S;
     35     for(int i = 0;i < rear;i++){
     36         for(int j = first[q[i]];j != -1;j = next[j])
     37             if(w[j] && d[v[j]] == -1){
     38                 d[v[j]] = d[q[i]] + 1;
     39                 q[rear++] = v[j];
     40                 if(v[j] == T)   return 1;
     41             }
     42     }
     43     return 0;
     44 }
     45 
     46 int dfs(int cur,int a){
     47     if(cur == T)    return a;
     48     for(int &i = work[cur];i != -1;i = next[i]){
     49         if(w[i] && d[v[i]] == d[cur] + 1)
     50             if(int t = dfs(v[i],min(a,w[i]))){
     51                 w[i] -= t;w[i^1] += t;
     52                 return t;
     53             }
     54     }
     55     return 0;
     56 }
     57 
     58 int dinic(){
     59     int ans = 0;
     60     while(bfs()){
     61         memcpy(work,first,sizeof(first));
     62         while(int t = dfs(S,INF))   ans += t;
     63     }
     64     return ans;
     65 }
     66 
     67 int cal(int id,int row_cnt){
     68     int cnt = 0,pos = id+row_cnt;
     69     for(int i = first[pos];i != -1;i = next[i])
     70         if(v[i] <= row_cnt) cnt += w[i];
     71     return cnt+1;
     72 }
     73 
     74 int main()
     75 {
     76     int n,m;
     77     char str[10];
     78     while(scanf("%d%d",&n,&m) == 2){
     79         init();
     80         int row_cnt,col_cnt,id;
     81         row_cnt = col_cnt = id = 0;
     82         for(int i = 1;i <= n;i++){
     83             for(int j = 1;j <= m;j++){
     84                 scanf("%s",str);
     85                 if(str[0] == '.'){
     86                     map[i][j] = ++id;
     87                 }else{
     88                     map[i][j] = -1;
     89                     if(str[0] != 'X'){
     90                         int tmp = (str[0]-'0')*100 + (str[1]-'0')*10 + str[2]-'0';
     91                         col[++col_cnt].x = i;
     92                         col[col_cnt].y = j;
     93                         col[col_cnt].z = tmp;
     94                     }
     95                     if(str[4] != 'X'){
     96                         int tmp = (str[4]-'0')*100 + (str[5]-'0')*10 + str[6]-'0';
     97                         row[++row_cnt].x = i;
     98                         row[row_cnt].y = j;
     99                         row[row_cnt].z = tmp;
    100                     }
    101                 }
    102             }
    103         }
    104         S = 0,T = row_cnt+id+col_cnt+1;
    105         for(int i = 1;i <= row_cnt;i++){
    106             int x = row[i].x;
    107             int y = row[i].y;
    108             int cnt_len = 0;
    109             for(y = y+1;y <= m;y++){
    110                 if(map[x][y] != -1){
    111                     cnt_len++;
    112                     add_edge(i,row_cnt+map[x][y],8);
    113                 }
    114                 else   break;
    115             }
    116             add_edge(S,i,row[i].z-cnt_len);
    117         }
    118         for(int i = 1;i <= col_cnt;i++){
    119             int x = col[i].x;
    120             int y = col[i].y;
    121             int cnt_len = 0;
    122             for(x = x+1;x <= n;x++){
    123                 if(map[x][y] != -1){
    124                     cnt_len++;
    125                     add_edge(row_cnt+map[x][y],row_cnt+id+i,8);
    126                 }
    127                 else    break;
    128             }
    129             add_edge(row_cnt+id+i,T,col[i].z-cnt_len);
    130         }
    131         dinic();
    132         for(int i = 1;i <= n;i++){
    133             for(int j = 1;j <= m;j++){
    134                 if(map[i][j] == -1) printf("_ ");
    135                 else    printf("%d ",cal(map[i][j],row_cnt));
    136             }
    137             printf("
    ");
    138         }
    139     }
    140     return 0;
    141 }
    View Code
  • 相关阅读:
    单击按钮左键弹起菜单
    高亮选中MEMO某一行
    DelphiTXT文档编辑器
    桌面名人名言
    判断richtextbox选中的是否为图片
    数组
    解决Linux下IDEA无法使用ibus输入法的问题和tip乱码
    Spring实现AOP的多种方式
    java术语(PO/POJO/VO/BO/DAO/DTO)
    idea intellij对Spring进行单元测试
  • 原文地址:https://www.cnblogs.com/zhexipinnong/p/3386959.html
Copyright © 2020-2023  润新知