例题6-8 树(Tree, UVa 548)

来源:互联网 发布:咖啡机推荐 知乎 编辑:程序博客网 时间:2024/06/02 06:00
很基础的一道题,用了分治法建树,dfs求最值。
#include <iostream>#include <string>#include <vector>#include <stack>#include <queue>#include <deque>#include <set>#include <map>#include <algorithm>#include <functional>#include <sstream>#include <utility>#include <cstring>#include <cstdio>#include <cstdlib>#include <ctime>#include <cmath>#include <cctype>#define CLEAR(a, b) memset(a, b, sizeof(a))#define IN() freopen("in.txt", "r", stdin)#define OUT() freopen("out.txt", "w", stdout)#define LL long long#define maxn 10005#define maxm 100005#define mod  10007#define INF 1e16+5#define EPS 1e-7#define PI 3.1415926535898#define N 4294967296using namespace std;//-------------------------CHC------------------------------//struct Node {int val;Node *left, *right;Node () : left(NULL), right(NULL) { }};int in[maxn], pre[maxn], post[maxn], idx;int minval, minsum, sum;void GetPre(int pos, int l1, int r1, int l2, int r2) {pre[pos] = post[r2 - 1];int root = find(in + l1, in + r1, pre[pos]) - in;int left = root - l1;if (left >= 1) GetPre(pos + 1, l1, root, l2, l2 + left);if (r1 - root - 1 >= 1) GetPre(pos + 1 + left, root + 1, r1, l2 + left, r2 - 1);}void build(Node *root, int l1, int r1, int l2, int r2) {root->val = post[r2 - 1];//printf("val = %d\n", root->val);int mid = find(in + l1, in + r1, root->val) - in;int left = mid - l1, right = r1 - mid - 1;if (left >= 1) {root->left = new Node();build(root->left, l1, mid, l2, l2 + left);}if (right >= 1) {root->right = new Node();build(root->right, mid + 1, r1, l2 + left, r2 - 1);}}void solve(Node *root) {sum += root->val;if (root->left) solve(root->left);if (root->right) solve(root->right);if (!root->right && !root->left)if(!minval || sum < minsum) minsum = sum, minval = root->val;sum -= root->val;}int main() {#ifdef _DEBUGIN(); OUT();#endifstring read1, read2;while (getline(cin, read1) && getline(cin, read2)) {stringstream s1(read1), s2(read2);idx = 0;while (s1 >> in[idx] && s2 >> post[idx++]);//GetPre(0, 0, idx, 0, idx);//for (int i = 0; i < idx; ++i) printf("%d ", pre[i]); puts("");Node *root = new Node();build(root, 0, idx, 0, idx);sum = minsum = minval = 0;solve(root);cout << minval << endl;}return 0;}
两点改进,sum可以作为形参来达到相同的效果,可以直接用val作为地址建树。
改进后代码真的简洁。。。
#include <iostream>#include <string>#include <vector>#include <stack>#include <queue>#include <deque>#include <set>#include <map>#include <algorithm>#include <functional>#include <sstream>#include <utility>#include <cstring>#include <cstdio>#include <cstdlib>#include <ctime>#include <cmath>#include <cctype>#define CLEAR(a, b) memset(a, b, sizeof(a))#define IN() freopen("in.txt", "r", stdin)#define OUT() freopen("out.txt", "w", stdout)#define LL long long#define maxn 10005#define maxm 100005#define mod  10007#define INF 1e16+5#define EPS 1e-7#define PI 3.1415926535898#define N 4294967296using namespace std;//-------------------------CHC------------------------------//int in[maxn], post[maxn], lch[maxn], rch[maxn], idx;int minval, minsum, sum;int build(int l1, int r1, int l2, int r2) {int root = post[r2 - 1];int mid = find(in + l1, in + r1, root) - in;int left = mid - l1, right = r1 - mid - 1;if (left >= 1) lch[root] = build(l1, mid, l2, l2 + left);if (right >= 1) rch[root] = build(mid + 1, r1, l2 + left, r2 - 1);return root;}void BFS(int root, int sum) {sum += root;if (lch[root]) BFS(lch[root], sum);if (rch[root]) BFS(rch[root], sum);if (!lch[root] && !rch[root])if(!minval || sum < minsum) minsum = sum, minval = root;}int main() {#ifdef _DEBUGIN(); OUT();#endifstring in_order, post_order;while (getline(cin, in_order) && getline(cin, post_order)) {CLEAR(lch, 0); CLEAR(rch, 0);stringstream s1(in_order), s2(post_order);idx = 0;while (s1 >> in[idx] && s2 >> post[idx++]);int root = build(0, idx, 0, idx);sum = minsum = minval = 0;BFS(root, 0);cout << minval << endl;}return 0;}


原创粉丝点击