博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 2242 考研路茫茫——空调教室(边双连通)
阅读量:6508 次
发布时间:2019-06-24

本文共 2387 字,大约阅读时间需要 7 分钟。

HDU 2242 考研路茫茫——空调教室

思路:求边双连通分量。然后进行缩点,点权为双连通分支的点权之和,缩点完变成一棵树,然后在树上dfs一遍就能得出答案

代码:

#include 
#include
#include
#include
#include
using namespace std;const int N = 10005;const int M = 20005;int n, m, val[N];struct Edge { int u, v, id; bool iscut; Edge() {} Edge(int u, int v, int id) { this->u = u; this->v = v; this->id = id; this->iscut = false; }} edge[M * 2], cut[M];int en, first[N], next[M], cutn;void add_edge(int u, int v, int id) { edge[en] = Edge(u, v, id); next[en] = first[u]; first[u] = en++;}int pre[N], dfn[N], bccno[N], bccval[N], bccn, dfs_clock;void dfs_cut(int u, int fa) { pre[u] = dfn[u] = ++dfs_clock; for (int i = first[u]; i + 1; i = next[i]) { int v = edge[i].v; if (edge[i].id == fa) continue; if (!pre[v]) { dfs_cut(v, edge[i].id); dfn[u] = min(dfn[u], dfn[v]); if (dfn[v] > pre[u]) { edge[i].iscut = edge[i^1].iscut = true; cut[cutn++] = edge[i]; } } else dfn[u] = min(dfn[u], pre[v]); }}void find_cut() { dfs_clock = 0; cutn = 0; memset(pre, 0, sizeof(pre)); for (int i = 0; i < n; i++) if (!pre[i]) dfs_cut(i, -1);}void dfs_bcc(int u) { pre[u] = 1; bccno[u] = bccn; bccval[bccn] += val[u]; for (int i = first[u]; i + 1; i = next[i]) { if (edge[i].iscut) continue; int v = edge[i].v; if (pre[v]) continue; dfs_bcc(v); }}vector
bcc[N];void find_bcc() { bccn = 0; memset(bccval, 0, sizeof(bccval)); memset(pre, 0, sizeof(pre)); for (int i = 0; i < n; i++) { if (!pre[i]) { dfs_bcc(i); bccn++; } }}const int INF = 0x3f3f3f3f;int ans, tot;int gao(int u, int fa) { int sum = bccval[u]; for (int i = 0; i < bcc[u].size(); i++) { int v = bcc[u][i]; if (v == fa) continue; int tmp = gao(v, u); sum += tmp; ans = min(ans, abs(tot - 2 * tmp)); } return sum;}int main() { while (~scanf("%d%d", &n, &m)) { en = 0; memset(first, -1, sizeof(first)); tot = 0; for (int i = 0; i < n; i++) { scanf("%d", &val[i]); tot += val[i]; } int u, v; for (int i = 0; i < m; i++) { scanf("%d%d", &u, &v); add_edge(u, v, i); add_edge(v, u, i); } find_cut(); find_bcc(); if (cutn == 0) { printf("impossible\n"); continue; } for (int i = 0; i < bccn; i++) bcc[i].clear(); for (int i = 0; i < cutn; i++) { int u = bccno[cut[i].u]; int v = bccno[cut[i].v]; bcc[u].push_back(v); bcc[v].push_back(u); } ans = INF; gao(0, -1); printf("%d\n", ans); } return 0;}

转载地址:http://xjbfo.baihongyu.com/

你可能感兴趣的文章
btrfs的使用(案例讲解)
查看>>
rpm db 损坏
查看>>
分布式事务-二阶段提交与三阶段提交
查看>>
安装配置samba服务器和客户端
查看>>
filebeat 配置文件详解
查看>>
Swift与OC混编
查看>>
CentOS 5 (64位)下lnmp平台搭建
查看>>
redhat 6.5 配置WAS控制台中文
查看>>
mysql实现vsftp虚拟用户访问
查看>>
记录一次处理https监听不正确的过程
查看>>
Zabbix使用SMTP发送邮件报警及定制邮件报警内容
查看>>
SCOM 2012 SP1服务器上安装和配置Veeam MP for VMware
查看>>
UDP中转服务器
查看>>
多核编程的四层境界
查看>>
Windows Phone 实用开发技巧(11):让StackPanel中的控件靠右对齐
查看>>
小记如何修改xen模块
查看>>
centos访问windowsxp共享资源指南.
查看>>
实时游戏对战引擎Photon
查看>>
C语言位操作控件属性
查看>>
nginx的安装及基本配置,及多个域名服务
查看>>