zoukankan      html  css  js  c++  java
  • uva 11082 Matrix Decompressing 【 最大流 】

    只看题目的话~~怎么也看不出来是网络流的题目的说啊~~~~

    建图好神奇~~

    最开始不懂---后来看了一下这篇--

    http://www.cnblogs.com/AOQNRMGYXLMV/p/4280727.html

    建立源点 st = 0,汇点 ed = r+c

    因为正整数的范围是1到20,而流量可以是0,所以先将矩阵里面的每个数减去1,到最后输出答案的时候再加上1

    把每一行看做一个节点 x,编号为1到r

    把每一列看做一个节点y,编号为r+1到r+c

    st到x连边,容量为 Ai '- c

    y到ed连边,容量为Bi' - r

    x到y连边,容量为19

    这样再用一下 dinic

    节点xi到yj的流量就是格子(i,j) - 1之后的值

    这句话最开始非常非常的不理解-------

    后来搜了下题解

    因为yj的流量来自于各个x

    同样的,xi的流量流向各个y,所以(i,j)这个格子的流量来源是xi

    大概像这个图这样

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #include<algorithm>
      5 #include<queue>
      6 using namespace std;
      7 
      8 const int maxn = 10005;
      9 const int INF = (1 << 30) - 1;
     10 
     11 struct Edge{
     12     int v,next,c;
     13 }e[maxn];
     14 
     15 int st,ed,lev[maxn],first[maxn],now[maxn],ecnt;
     16 int r,c;
     17 
     18 void init(){
     19     memset(first,-1,sizeof(first));
     20     ecnt = 0;
     21 }
     22 
     23 void addedges(int u,int v,int c){
     24     e[ecnt].next = first[u];
     25     e[ecnt].v = v;
     26     e[ecnt].c = c;
     27     first[u] = ecnt++;
     28     
     29     e[ecnt].next = first[v];
     30     e[ecnt].v = u;
     31     e[ecnt].c = 0;
     32     first[v] = ecnt++;
     33 }
     34 
     35 bool bfs(){
     36     queue<int> q;
     37     while(!q.empty()) q.pop();
     38     q.push(st);
     39     memset(lev,-1,sizeof(lev));
     40     lev[st] = 0;
     41     while(!q.empty()){
     42         int x = q.front();q.pop();
     43         for(int i = first[x];~i;i = e[i].next){
     44             int v = e[i].v;
     45             if(lev[v] < 0 && e[i].c > 0){
     46                 lev[v] = lev[x] + 1;
     47                 q.push(v);
     48             }
     49         }
     50     }
     51     return lev[ed] != -1;
     52 }
     53 
     54 int dfs(int p,int minf){
     55     if(p == ed || minf == 0) return minf;
     56     for(int &i = now[p];~i;i = e[i].next){
     57         int v = e[i].v;
     58         if(lev[v] == lev[p] + 1 && e[i].c > 0){
     59             int d = dfs(v,min(e[i].c,minf));
     60             if(d > 0){
     61                 e[i].c -= d;
     62                 e[i^1].c += d;
     63                 return d;
     64             }
     65         }
     66     }
     67     return 0;
     68 }
     69 
     70 int dinic(){
     71     int max_flow = 0,p1;
     72     while(bfs()){
     73         memcpy(now,first,sizeof(first));
     74         while((p1 = dfs(st,INF)) > 0)
     75         max_flow += p1;
     76     }
     77     return max_flow;
     78 }
     79 
     80 int ans[55][55];
     81 
     82 int main(){
     83     int T;
     84     scanf("%d",&T);
     85     int kase = 0;
     86     while(T--){
     87         scanf("%d %d",&r,&c);
     88         init();
     89         st = 0;ed = r+c+1;
     90         
     91         int last = 0,cur;        
     92         for(int i = 1;i <= r;i++){
     93             scanf("%d",&cur);
     94             addedges(st,i,cur-last-c);
     95             last = cur;
     96         }
     97         
     98         last = 0;
     99         for(int i = 1;i <= c;i++){
    100             scanf("%d",&cur);
    101             addedges(i + r,ed,cur-last-r);
    102             last = cur;
    103         }
    104         
    105         for(int i = 1;i <= r;i++)
    106             for(int j = 1;j <= c;j++) addedges(i,j+r,19);
    107         
    108         int res = dinic();
    109         
    110         for(int u = 1;u <= r;u++){
    111             for(int i = first[u];~i;i = e[i].next){
    112                 int v = e[i].v;
    113                 ans[u][v-r] = 19 - e[i].c;
    114             }
    115         }
    116         
    117         printf("Matrix %d
    ",++kase);
    118         for(int i = 1;i <= r;i++){
    119             printf("%d",ans[i][1] + 1);
    120             for(int j = 2;j <= c;j++)
    121             printf(" %d",ans[i][j] + 1);
    122             printf("
    ");
    123         }
    124         if(T) puts("");
    125     }
    126     return 0;
    127 }
    View Code
  • 相关阅读:
    Linux:DHCP服务配置
    调整 全局jvm 大小 tomcat 调整jvm大小
    Arts打卡第8周
    mysql 对返回的值是null进行判断和重新赋值
    从xml中返回的对象,和new 返回的对象时不同的。
    检查时异常和运行是异常 + 事务回滚 +隔离级别
    怎么在for循环中新建出不同的list
    mysql中查询某个字段重复的数据
    Arts打卡第7周
    将Excel文件导入到Navicat Premium中日期变为0000-00-00
  • 原文地址:https://www.cnblogs.com/wuyuewoniu/p/4713408.html
Copyright © 2011-2022 走看看