2019牛客多校第二场
D.Kth Minimum Clique(dijkstra+bitset+二进制)
- 题意:从图中随机选几个点,如果这些点连通,那么就称为团.团的价值是所有点的和.求第小的团.
一开始想到的算法- 如果从合法状态然后增广,就可以避免走到很多非法状态,然后用一个last避免重复
cin>>bit[i]bitset不能这样输入
#include<bits/stdc++.h> #define ll long long using namespace std; const int maxn = 105; ll s[maxn]; bitset<100> bit[maxn]; int n, k; struct node { bitset<100> now; int last = 0; ll val = 0; node(bitset<100> _now = 0, int _last = 0, ll _val = 0) { now = _now; last = _last; val = _val; } bool operator<(const node &c) const { return val > c.val; } }; priority_queue<node> que; ll dijkstra() { node st; st.now.reset(); que.push(st); while (!que.empty()) { st = que.top(); que.pop(); if (--k == 0) { return st.val; } for (int i = st.last; i < n; ++i) { if (!st.now[i] && ((st.now & bit[i]) == st.now)) { st.now.set(i); que.push(node(st.now, i + 1, st.val + s[i])); st.now.reset(i); } } } return -1; } int main() { ios::sync_with_stdio(false); cin.tie(0); cin >> n >> k; string str; for (int i = 0; i < n; ++i) cin >> s[i]; for (int i = 0; i < n; ++i) { cin >> str; for (int j = 0; j < n; ++j) { if (str[j] == '1')bit[i].set(j); else bit[i].reset(j); } } cout << dijkstra() << endl; return 0; }
Second Large Rectangle(单调栈+思维)
题意:第二大的全1子矩阵
求第一大的会,算法竞赛进阶上有模板.直接通过单调栈即可.
然后这题我也直接套了模板,但是错了
没考虑这个样例
3 3
101
111
111因为他有一个合并的操作,然后我一开始的写法不会出现4,要搞一个width-1才行
#include "bits/stdc++.h" using namespace std; typedef long long ll; const int mod = 1e9 + 7; const int maxn = 1010; const int inf = 0x3f3f3f3f; char s[maxn][maxn]; int sum[maxn]; int que[maxn]; int w[maxn]; int main() { //freopen("in.txt", "r", stdin); int n, m; scanf("%d%d", &n, &m); for (int i = 0; i < n; ++i) { scanf("%s", s[i]); } int top; int maxx = 0, cmaxx = 0; for (int i = 0; i < n; ++i) { top = 0; for (int j = 0; j < m; ++j) { w[j] = 0; if (s[i][j] == '1') { sum[j] += 1; } else sum[j] = 0; } sum[m] = 0; for (int j = 0; j <= m; ++j) { if (sum[j] > que[top]) { que[++top] = sum[j]; w[top] = 1; } else { int width = 0; while (sum[j] < que[top]) { width += w[top]; if ((width - 1) * que[top] > maxx) { cmaxx = maxx; maxx = (width - 1) * que[top]; } else if ((width - 1) * que[top] > cmaxx) { cmaxx = (width - 1) * que[top]; } if (width * que[top] > maxx) { cmaxx = maxx; maxx = width * que[top]; } else if (width * que[top] > cmaxx) { cmaxx = width * que[top]; } top--; } que[++top] = sum[j]; w[top] = width + 1; } } } printf("%d\n", cmaxx); return 0; }