題目鏈接: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");
else
printf("%d\n", t);
}
return 0;
}