hdu 2242 (Tarjan + 树形dp)

来源:互联网 发布:win8电脑屏幕录制软件 编辑:程序博客网 时间:2024/06/10 04:27

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2242

挺基础的一个图论dp综合题目, 开了IO以后暂时rank1。。。。

#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#include <vector>#include <queue>#include <string>#include <cctype>#include <set>#include <map>using namespace std;inline int readint() {char c = getchar();while (!isdigit(c)) c = getchar();int x = 0;while (isdigit(c)) {x = x * 10 + c - '0';c = getchar();}return x;}int buf[10];inline void writeint(int x) {int p = 0;if (x == 0) p++;else while (x) {buf[p++] = x % 10;x /= 10;}for (int j = p - 1; j >= 0; j--)putchar('0' + buf[j]);}const int N = 10005;const int M = N << 3;struct Tree {struct Edge {int v;Edge* next;void init(int a, Edge* e) {this->v = a, next = e;}};int key, n, rt;Edge * head[N];Edge* it;Edge E[M];bool vis[N];int W[N], sum[N], res, tot;void init(int n) {this->n = n;for (int i = 0; i < n; i++) {head[i] = 0, W[i] = 0;vis[i] = 0;}it = E;}void add(int u, int v) {it->init(v, head[u]);head[u] = it++;it->init(u, head[v]);head[v] = it++;}void dfs(int u, int fa) {sum[u] = W[u];vis[u] = 1;for (Edge* e = head[u]; e; e = e->next) {int v = e->v;if (v == fa || vis[v]) continue;dfs(v, u);sum[u] += sum[v];}if (fa != -1) {if (res > labs(tot - sum[u] - sum[u])) {res = labs(tot - sum[u] - sum[u]);}}}int gao() {tot = 0;for (int i = 0; i < n; i++)tot += W[i];res = tot;dfs(0, -1);return res;}}T;struct Graph {struct Edge {int v;bool iscut;Edge* next, * pair;void init(int a, Edge* e1, Edge* e2) {this->v = a, next = e1;pair = e2;iscut = 0;}};Edge E[M], * head[N];int pre[N], low[N], no[N], W[N];Edge* it;int tdfn;int n, id;void init(int n) {this->n = n;for (int i = 0; i < n; i++) {head[i] = 0;pre[i] = 0;}it = E;tdfn = 1;}void add(int u, int v) {it->init(v, head[u], it + 1);head[u] = it++;it->init(u, head[v], it - 1);head[v] = it++;}int dfs(int u, int fa) {int lowu = pre[u] = tdfn++;for (Edge* e = head[u]; e; e = e->next) {int v = e->v;if (!pre[v]) {int lowv = dfs(v, u);lowu = min(lowv, lowu);if (lowv > pre[u]) {e->iscut = 1;e->pair->iscut = 1;}}else if(v != fa && pre[v] < pre[u]) { lowu = min(lowu, pre[v]);}}low[u] = lowu;return lowu;}void dfs(int u) {no[u] = id;for (Edge* e = head[u]; e; e = e->next) {if (e->iscut) continue;int v = e->v;if (no[v] == -1)dfs(v);    }}        int run() {dfs(0, -1);for (int i = 0; i < n; i++)if (!pre[i]) return -1;id = 0;for (int i = 0; i < n; i++) no[i] = -1;for (int i = 0; i < n; i++)if (no[i] == -1) {dfs(i);id++;}if (id == 1) return -1;T.init(id);for (int i = 0; i < n; i++) {for (Edge* e = head[i]; e; e = e->next) {int v = e->v;if (!e->iscut) continue;T.add(no[i], no[v]);e->pair->iscut = 0;}}for (int i = 0; i < n; i++)T.W[no[i]] += W[i];return T.gao();}}G;int main() {int n, m, u, v, t;while (~scanf("%d%d", &n, &m)) {G.init(n);for (int i = 0; i < n; i++)t = readint(), G.W[i] = t;for (int i = 0; i < m; i++)u = readint(), v = readint(), G.add(u, v);t = G.run();if (t == -1)puts("impossible");elseprintf("%d\n", t);}return 0;}