记录编号 125276 评测结果 AAAAAAAAAA
题目名称 [NOIP 2010]引水入城 最终得分 100
用户昵称 Gravatar天一阁 是否通过 通过
代码语言 C++ 运行时间 0.712 s
提交时间 2014-10-08 07:48:07 内存使用 1.53 MiB
显示代码纯文本
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cstdio>

#define Maxn 503
#define clean(x, y) memset(x, y, sizeof(x))
#define INF 0x7fffffff

using namespace std;

struct node {int x, y;} line[Maxn] = {0};
queue <node> q;

int n, m, h[Maxn][Maxn] = {0};
bool v[Maxn] = {0}, flag[Maxn][Maxn] = {0};
int f[Maxn] = {0};

const int xx[4] = {0, 0, 1, -1};
const int yy[4] = {1, -1, 0, 0};

void flood(int now, int x, int y) { //把本题化为线段的最小代价覆盖 
    if (x > n || x < 1 || y > m || y < 1) return;
    if (x == n) {
		v[y] = true; //种子填充法 
		if (line[now].x == 0 || line[now].x > y) {
			line[now].x = y;
		}
		if (line[now].y == 0 || line[now].y < y) {
			line[now].y = y;
		}	
	}
    flag[x][y] = true;
    if (!flag[x + 1][y] && h[x + 1][y] < h[x][y]) flood(now, x + 1, y);
    if (!flag[x][y + 1] && h[x][y + 1] < h[x][y]) flood(now, x, y + 1);
    if (!flag[x - 1][y] && h[x - 1][y] < h[x][y]) flood(now, x - 1, y);
    if (!flag[x][y - 1] && h[x][y - 1] < h[x][y]) flood(now, x, y - 1);
}

bool cmp (const node a, const node b) {return a.y < b.y;}

void init() {
	cin >> n >> m;
	for (int i = 1;i <= n;i ++) {
		for (int j = 1;j <= m;j ++) {
			cin >> h[i][j];
		}
	}
	for (int i = 1;i <= m;i ++) {
		memset(flag, 0, sizeof(flag));
		flood(i, 1, i);
	}
	bool judge = true;
	for (int i = 1;i <= m;i ++) { //先填充一遍,看是否可行 
		 judge = judge && v[i];
	}
	if (!judge) {
		int tot = 0;
		cout << '0' << endl;
		for (int i = 1;i <= m;i ++) {
			if (!v[i]) tot ++; //直接统计输出 
		}
		cout << tot << endl;
		return ;
	} else {
		cout << '1' << endl;
		sort(line + 1, line + m + 1, cmp); //以y为关键字排序
		int tmp = 1;
		f[0] = 0;
		for (int i = 1;i <= m;i ++) {
			if (i >= line[tmp].y) {
				while (tmp <= m && line[tmp].y < i) tmp ++;
				while (i == line[tmp].y) { //剪裁线段
					if (line[tmp].x == 1 || f[line[tmp].x - 1] != 0) {
						if (f[i] == 0 || f[i] > f[line[tmp].x - 1] + 1) {
							f[i] = f[line[tmp].x - 1] + 1;
						}
					}
					tmp ++;
				}
				if (f[i] != 0) {
					for (int j = 1;j < i;j ++) {
						if (f[j] == 0 || f[j] > f[i]) {
							f[j] = f[i];
						} //化为前缀
					}
				}
			}
		}
		cout << f[m] << endl;
	}
}

int main() {
	freopen("flow.in", "r", stdin);
	freopen("flow.out", "w", stdout);
	ios :: sync_with_stdio(false);
	init();
	return 0;
}