Largest Submatrix of All 1’s POJ - 3494(笛卡尔树,求全位1的最大子矩阵)

题意:给一个n*m的01矩阵,求全为1的最大子矩阵。
  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstdio>
  4 #include<cstring>
  5 #include<queue>
  6 #include<set>
  7 #include<cmath>
  8 #include<string>
  9 #include<map>
 10 #include<vector>
 11 #include<ctime>
 12 #include<stack>
 13 using namespace std;
 14 #define mm(a,b) memset(a,b,sizeof(a))
 15 #define ll long long
 16 #define ull unsigned long long
 17 #define mm(a,b) memset(a,b,sizeof(a))
 18 const int maxn=2e3+10;
 19 const ll mod=1e9+7;
 20 int c[maxn][maxn];
 21 int a[maxn],maxx=0;
 22 struct Cartesian_Tree {
 23     //创建笛卡尔树的结构
 24     struct node {
 25         int index;
 26         int value;
 27         int parent;
 28         int child[2];
 29         node() {}
 30         node(int index, int value, int parent) : index(index), value(value), parent(parent) {
 31             child[0] = child[1] = 0;
 32         }
 33     }tree[maxn];
 34     
 35     //初始化笛卡尔树,以0作为根,防止下面算法中A循环异常
 36     void init() {
 37         tree[0] = node(0, 0, 0);
 38     }
 39     
 40     int root, l[maxn], r[maxn];
 41     
 42     //创建笛卡尔树
 43     void build(int n, int *a) {
 44         for (int i = 1; i <= n; i++) {
 45             tree[i] = node(i, a[i], 0);
 46         }
 47         for (int i = 1; i <= n; i++) {
 48             int k = i - 1;
 49             //A循环
 50             //一直找到比i位置小的位置k
 51             while (tree[k].value > tree[i].value)
 52                 k = tree[k].parent;
 53             
 54             //将父节点的右子树放到自己的左子树上,因为不能改变他们映射后的序列位置,因此是将右子树放到左子树
 55             tree[i].child[0] = tree[k].child[1];
 56             //父节点的右子树重新指向
 57             tree[k].child[1] = i;
 58             //设置i的父节点
 59             tree[i].parent = k;
 60             //设置原本为右子树,现改为当前节点的左子树的父亲
 61             tree[tree[i].child[0]].parent = i;
 62         }
 63         //笛卡尔树的根节点设置为根节点的右子树节点(即我们插入的1~n范围里的最值)
 64         root = tree[0].child[1];
 65     }
 66     //通过DFS进行一下判断,该判断是下图的解决方案
 67     int DFS(int root) {
 68         if (!root) return 0;
 69         int sz = DFS(tree[root].child[0]);
 70         sz += DFS(tree[root].child[1]);
 71         maxx=max(maxx,(sz + 1) * tree[root].value);
 72         return sz + 1;
 73     }
 74 }tree;
 75 int main()
 76 {
 77     int n,m;
 78     while(scanf("%d %d",&n,&m)!=EOF){
 79         maxx=0;
 80         getchar();
 81         for(int i=1;i<=n;i++){
 82             for(int j=1;j<=m;j++){
 83                 scanf("%d",&c[i][j]);
 84             }
 85         }
 86         mm(a,0);
 87         for(int i=1;i<=n;i++){
 88             for(int j=1;j<=m;j++){
 89                 if(c[i][j]==1)
 90                     a[j]++;
 91                 else
 92                     a[j]=0;
 93             }
 94             tree.init();
 95             tree.build(m,a);
 96             tree.DFS(tree.root);
 97         }
 98         printf("%d\n",maxx);
 99     }
100 }

 

 
posted @ 2020-03-04 20:44  Tangent_1231  阅读(196)  评论(0编辑  收藏  举报