社区讨论
求助!!复杂度为O(n*n*m+n) 然而T了8个点
P1514[NOIP 2010 提高组] 引水入城参与者 3已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @mi7xxuj1
- 此快照首次捕获于
- 2025/11/21 05:26 4 个月前
- 此快照最后确认于
- 2025/11/21 05:26 4 个月前
CPP
#include<iostream>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 510;
int a[N][N], vis[N][N], fin[N], tmp[N], n, m, cnt = 0;;
int dx[] = {1, -1, 0, 0}, dy[] = {0, 0, -1, 1};
struct node {
int x, y;
};
struct segment {
int l, r, f;
} seg[N];
bool cmp(segment p, segment q) {
return p.r > p.r;
}
void bfs(int s) {
memset(vis, 0, sizeof(vis));
memset(tmp, 0, sizeof(tmp));
queue<node> q;
q.push((node) {1, s});
vis[1][s] = 1;
while(q.size()) {
int x = q.front().x, y = q.front().y;
q.pop();
if(x == n) fin[y]= 1;// 该节点可灌溉
for(int i = 0; i < 4; i++) {
int nx = x+dx[i], ny = y+dy[i];
if(a[nx][ny]<a[x][y] && (nx>0&&nx<=n&&ny>0&&ny<=m) && !vis[nx][ny]) {
q.push((node) {nx, ny});
vis[nx][ny] = 1;
}
}
}
for(int i = 1; i <= m+1; i++) {//保存宽搜结果
if(!a[n][i-1] && a[n][i]) {
seg[++cnt].l = i;
seg[cnt].f = s;
}
if(!a[n][i] && a[n][i-1]) {
seg[cnt].r = i-1;
}
}
return;
}
int main() {
cin >> n >> m;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
cin >> a[i][j];
}
}
for(int i = 1; i <= m; i++) bfs(i);//宽搜求出每个点可以灌溉的区间
int flag = 0;
for(int i = 1; i <= m; i++)
if(!fin[i]) flag++;
if(flag) {
cout << 0 << endl << flag << endl;
return 0;
} else cout << 1 << endl;
//最少线段覆盖
sort(seg+1, seg+cnt+1, cmp);
seg[++cnt].l = 555;
int s = 1, ans = 0;
for(int i = 1; i <= cnt; i++){
if(seg[i].l > s){
--i;
ans++;
s = seg[i].r;
}
if(s >= m) break;
}
cout << ans << endl;
return 0;
}
回复
共 2 条回复,欢迎继续交流。
正在加载回复...