• UVA 11082 Matrix Decompressing 矩阵解压(最大流,经典)


    题意:

      知道矩阵的前i行之和,和前j列之和(任意i和j都可以)。求这个矩阵。每个格子中的元素必须在1~20之间。矩阵大小上限20*20。

    思路:

      这么也想不到用网络流解决,这个模型很不错。假设这个矩阵的每一行是水管,每一列是水管,每行有出水口流到每一列,这样想比较好理解。然后每行的流量和每列的流量知道,就可以建图了。

      建图过程,每行对应一个点,每列对应1个点,每行都可以流到每列,所以他们之间有边。我们得假设他们是如何流向的,不如设从行流向列,那么添加源点,流向每行;添加汇点,被每列汇流。容量怎么设?我们要让每行都满流就行了,那么行之和就是源点到该行的容量,同理汇点也如此。但是每行流向每列呢?注意每个格子的元素必须在1~20之间,所以把容量设为20,别让它流太多了。

      注意到元素必须在1~20之间!!!那么这样增广路的话会出现有的完全0流怎么办?先将每个格子中的元素自减1,它的流下限总不会为负吧,计算完输出时再加回去不就行了。

      1 #include <bits/stdc++.h>
      2 #define LL long long
      3 #define pii pair<int,int>
      4 #define INF 0x7f7f7f7f
      5 using namespace std;
      6 const int N=10000+100;
      7 
      8 struct node
      9 {
     10     int from;
     11     int to;
     12     int cap;
     13     int flow;
     14 }edge[N];
     15 
     16 int row[30];
     17 int col[30];
     18 int edge_cnt;
     19 vector<int> vect[1000];
     20 
     21 void add_node(int from,int to,int cap,int flow)
     22 {
     23     edge[edge_cnt].from=from;
     24     edge[edge_cnt].to=to;
     25     edge[edge_cnt].cap=cap;
     26     edge[edge_cnt].flow=flow;
     27     vect[from].push_back(edge_cnt);
     28     edge_cnt++;
     29 }
     30 
     31 void build_graph(int n,int m)
     32 {
     33     for(int i=1; i<=n; i++) //加源点
     34     {
     35         add_node(0, i, row[i], 0);
     36         add_node(i ,0, 0, 0);
     37     }
     38 
     39     for(int i=1; i<=m; i++) //汇点
     40     {
     41         add_node(n+i, n+m+1, col[i], 0);
     42         add_node(n+m+1, n+i, 0, 0);
     43     }
     44 
     45     for(int i=1; i<=n; i++) //行-列
     46     {
     47         for(int j=1; j<=m; j++)
     48         {
     49             add_node(i,n+j,19,0);
     50             add_node(n+j, i,0,0);
     51         }
     52     }
     53 }
     54 
     55 int flow[1000];
     56 int path[1000];
     57 int matrix[50][50];
     58 
     59 int BFS(int s,int e)
     60 {
     61     deque<int> que;
     62     que.push_back(s);
     63     flow[s]=INF;
     64 
     65     while(!que.empty())
     66     {
     67         int x=que.front();
     68         que.pop_front();
     69         for(int i=0; i<vect[x].size(); i++)
     70         {
     71             node e=edge[vect[x][i]];
     72             if(!flow[e.to] && e.cap>e.flow)
     73             {
     74                 path[e.to]=vect[x][i];
     75                 flow[e.to]=min(flow[e.from],e.cap-e.flow);
     76                 que.push_back(e.to);
     77             }
     78         }
     79         if(flow[e]) return flow[e];
     80     }
     81     return flow[e];
     82 }
     83 
     84 int cal(int s, int e)
     85 {
     86     int ans=0;
     87     while(true)
     88     {
     89         memset(flow,0,sizeof(flow));
     90         memset(path,0,sizeof(path));
     91 
     92         int tmp=BFS(s,e);
     93         if(tmp==0)  return ans;
     94 
     95         ans+=tmp;
     96         int ed=e;
     97         while(ed!=s)
     98         {
     99             int t=path[ed];
    100             edge[t].flow+=tmp;
    101             edge[t^1].flow-=tmp;
    102             ed=edge[t].from;
    103         }
    104 
    105     }
    106     return 0;
    107 }
    108 
    109 void get_ans(int n,int m)
    110 {
    111     for(int i=0; i<edge_cnt; i+=2)
    112     {
    113         node e=edge[i];
    114         if(e.to<n)  continue;
    115         matrix[e.from][e.to-n]=e.flow;
    116     }
    117     for(int i=1; i<=n; i++)
    118     {
    119         for(int j=1; j<=m; j++)
    120             printf("%d ", matrix[i][j]+1);
    121         printf("
    ");
    122     }
    123 }
    124 
    125 
    126 int main()
    127 {
    128     //freopen("input.txt", "r", stdin);
    129     int r, c, t, k, Case=0;
    130     cin>>t;
    131     while(t--)
    132     {
    133         for(int i=0; i<1000; i++)    vect[i].clear();
    134         memset(matrix,0,sizeof(matrix));
    135         memset(row,0,sizeof(row));
    136         memset(col,0,sizeof(col));
    137         memset(edge,0,sizeof(edge));
    138         edge_cnt=0;
    139 
    140 
    141         scanf("%d%d",&r,&c);
    142         for(int i=1; i<=r; i++)  //
    143             scanf("%d",&row[i]);
    144 
    145         for(int i=1; i<=c; i++)  //
    146             scanf("%d",&col[i]);
    147 
    148         for(int i=r; i>0; i--)  //换成每行-c
    149             row[i]-=row[i-1]+c;//细心点
    150         for(int i=c; i>0; i--)  //换成每列-r
    151             col[i]-=col[i-1]+r;
    152 
    153         printf("Matrix %d
    ",++Case);
    154         build_graph(r, c);
    155         cal(0, r+c+1);
    156         get_ans(r,c);
    157         if(t)   cout<<endl;
    158     }
    159     return 0;
    160 }
    AC代码
  • 相关阅读:
    ios下的appium 通过ipa包名启动app demo演示
    如何在Mac上获取App Store上的ipa用于ios下的appium 自动化测试
    Unittest命令行执行测试、执行测试发现操作实例
    nodejs之querystring模块
    nodejs之url模块
    微信小程序学习Course 5 view组件、input组件、button组件
    微信小程序学习Course 3-1 JS字符串对象学习
    微信小程序学习Course 2 关于WXSS一些样式
    微信小程序学习Course 4 事件
    微信小程序学习Course 1 微信小程序基本内容
  • 原文地址:https://www.cnblogs.com/xcw0754/p/4646140.html
Copyright © 2020-2023  润新知