HDU 2242 (Tarjan双连通缩点+树形DP)
来源:互联网 发布:mac使用github pages 编辑:程序博客网 时间:2024/05/19 22:01
n个点m条无向边,要去一条边得到两个连通分支,所以要去掉的一定是桥。先跑一边Tarjan找到所有的桥,然后双连通缩点,所有的双连通分量所成一个点,再用桥连接,得到一棵树。然后跑一遍树形DP。
代码:
// Header.#include <algorithm>#include <iostream>#include <sstream>#include <cstring>#include <cstdio>#include <vector>#include <string>#include <bitset>#include <queue>#include <cmath>#include <ctime>#include <set>#include <map>using namespace std;// Macrotypedef long long LL;#define TIME cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << "s." << endl;#define IN freopen("/Users/apple/input.txt", "r", stdin);#define OUT freopen("/Users/apple/out.txt", "w", stdout);#define mem(a, n) memset(a, n, sizeof(a))#define rep(i, n) for(int i = 0; i < (n); i ++)#define repD(i, n) for(int i = (n); i; i --)#define REP(i, t, n) for(int i = (t); i < (n); i ++)#define REPD(i, t, n) for(int i = (n); i > (t); i --)#define FOR(i, t, n) for(int i = (t); i <= (n); i ++)#define FORD(i, t, n) for(int i = (n); i >= (t); i --)#define ALL(v) v.begin(), v.end()#define Min(a, b) a = min(a, b)#define Max(a, b) a = max(a, b)#define put(a) printf("%d\n", a)#define ss(a) scanf("%s", a)#define si(a) scanf("%d", &a)#define sii(a, b) scanf("%d%d", &a, &b)#define siii(a, b, c) scanf("%d%d%d", &a, &b, &c)#define VI vector<int>#define pb push_back#define x first#define y secondconst int inf = 0x3f3f3f3f, N = 1e4 + 5, MOD = 1e9 + 7;// Macro endint T, cas = 0;int n, m, ne, ans, all, top, bch, dfsNum;int a[N], head[N], dfn[N], low[N], tree[N], sum[N], col[N], stack[N];vector<pair<int, int> > brige;bool vis[N];struct edge { int v, next;}e[10 * N];// Impvoid addEdge(int u, int v) { e[ne].v = v, e[ne].next = head[u], head[u] = ne ++;}void Tarjan(int u, int fa) { dfn[u] = low[u] = dfsNum ++; vis[u] = 1; stack[top++] = u; int flag = 0; for(int i = head[u]; i != -1; i = e[i].next) { int v = e[i].v; if(v == fa && !flag) { flag = 1; continue; } if(!vis[v]) { Tarjan(v, u); Min(low[u], low[v]); } else if(col[v] == -1) Min(low[u], dfn[v]); if(dfn[u] < low[v]) brige.pb(make_pair(u, v)); } if(low[u] == dfn[u]) { while(stack[top-1] != u) col[stack[--top]] = bch, sum[bch] += a[stack[top]]; top --; sum[bch] += a[stack[top]]; col[u] = bch ++; }}void build() { int sz = brige.size(); rep(i, sz) { int u = brige[i].x, v = brige[i].y; e[ne].v = col[v], e[ne].next = tree[col[u]]; tree[col[u]] = ne ++; e[ne].v = col[u], e[ne].next = tree[col[v]]; tree[col[v]] = ne ++; }}int dfs(int u) { int tmp = sum[u]; vis[u] = 1; for(int i = tree[u]; i != -1; i = e[i].next) { if(!vis[e[i].v]) tmp += dfs(e[i].v); } Min(ans, abs(all - 2 * tmp)); return tmp;}void init() { mem(tree, -1); mem(head, -1); mem(col, -1); mem(vis, 0); mem(sum, 0); brige.clear(); bch = top = all = ne = dfsNum = 0;}int main(){#ifdef LOCAL IN // OUT#endif while(sii(n, m) != EOF) { init(); rep(i, n) si(a[i]), all += a[i]; int u, v; rep(i, m) { sii(u, v); addEdge(u, v), addEdge(v, u); } Tarjan(0, 0); if(bch != 1) { build(); mem(vis, 0); ans = inf; dfs(0); put(ans); } else puts("impossible"); } return 0;}
0 0
- HDU 2242 (Tarjan双连通缩点+树形DP)
- HDU 4005 The war 边-双连通缩点+树形dp
- 【双连通分量(tarjan)+树形dp】HDU-2242-考研路茫茫——空调教室
- HDU 5409 双连通缩点
- HDU 5739 Fantasia(点双连通分量+树形DP)
- hdu 2242 (Tarjan + 树形dp)
- poj3694--Network(双连通缩点+lca)
- hdu 3394 Railway(Tarjan,点双连通分量)
- hdu 4612 Warm up 双连通缩点+树的直径
- Hdu 4612 Warm up (双连通缩点+树的直径)
- 双连通缩点 POJ 1515
- POJ 3532 双连通缩点
- HDU 2767 Proving Equivalences Tarjan 强连通缩点
- POJ 3694 Network (边双连通缩点、LCA)
- HDU 3072 Intelligence System (强连通缩点+简单最小树形图,4级)
- HDU 3686 Traffic Real Time Query System(点双连通缩点 + LCA)
- HDU 5739 (点双连通 树DP)
- hdu 3749 Financial Crisis(Tarjan,点双连通分量)
- 业火的向日葵 新娘大作战
- 京东支付逻辑存在不安全因素
- mysql_thread_end()
- OpenGL glBlendFunc 之 cocos2dx - ccBlendFunc 研究
- iOS远程推送之获取deviceToken
- HDU 2242 (Tarjan双连通缩点+树形DP)
- Hibernate 在事务管理下,save之后获取Id的方法
- Win10 Vbox 桥接找不到网卡的解决办法
- 常用数学符号表
- Leet Code Medium 3 Longest Substring Without Repeating Characters
- android调节屏幕亮度(包括只修改应用程序和修改系统)
- mysql_thread_init()
- mysql数据库常用的基本SQL语句--数据库表操作
- Qt Scene Graph渲染方式在不同系统的差异