http://acm.hdu.edu.cn/showproblem.php?pid=2242

题意:

思路:
首先求一下双连通分量,如果只有一个双连通分量,那么无论断哪根管子,图还是连通的。

最后只需要根据双连通分量重新建图,在树上进行dp,分成两部分的最小差值。这个具体看代码就可以了。

需要注意的是,这道题目是存在重边的,在这个点上我WA了好久,那么怎么处理重边呢?

设置一个重边标记,跳过第一次父亲结点的反向边,但是第二次的话就必须处理,此时就是双连通的了。

简单来说,如果图是没有重边的,那么我们在考虑反向边时,到父亲结点的反向边是不能考虑的,也就是else if(v!=fa)  lowu=min(lowu,pre[v])。

但是在这里是存在重边的,所以第一条父亲节点的反向边我们不能去考虑,但是之后就必须要去考虑,因为u,v之间如果有两条及以上的边,那它就是个双连通分量了,如果你用之前的(v!=fa)去判断,那肯定是错误的。

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<sstream>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int INF = 0x3f3f3f3f;
const int maxn=+; int n, m;
int tot;
int cnt;
int scc;
int ans;
int all_value;
int val[maxn];
int head[maxn];
int head2[maxn];
int dfs_clock;
int pre[maxn];
int low[maxn];
int eccno[maxn];
int sum[maxn]; stack<int> S; struct node
{
int v;
int next;
}e[+]; void addEdge(int u, int v)
{
e[tot].v=v;
e[tot].next=head[u];
head[u]=tot++;
} void addEdge2(int u, int v)
{
e[tot].v=v;
e[tot].next=head2[u];
head2[u]=tot++;
} void init()
{
tot=all_value=scc=dfs_clock=;
memset(head,-,sizeof(head));
memset(head2,-,sizeof(head2));
memset(sum,,sizeof(sum));
memset(pre,,sizeof(pre));
memset(eccno,,sizeof(eccno));
} int Tarjan(int u, int fa)
{
int flag=; //标价重边
int lowu=pre[u]=++dfs_clock;
S.push(u);
for(int i=head[u];i!=-;i=e[i].next)
{
int v=e[i].v;
if(v==fa && !flag) {flag=;continue;}//考虑重边的情况,相当重要!
if(!pre[v])
{
int lowv=Tarjan(v,u);
lowu=min(lowu,lowv);
}
else lowu=min(lowu,pre[v]);
}
if(pre[u]==lowu)
{
scc++;
for(;;)
{
int tmp=S.top(); S.pop();
eccno[tmp]=scc;
sum[scc]+=val[tmp];
if(tmp==u) break;
}
}
return low[u]=lowu;
} int dp(int u, int fa)
{
int ALL=sum[u];
for(int i=head2[u];i!=-;i=e[i].next)
{
int v=e[i].v;
if(v==fa) continue;
ALL+=dp(v,u); }
ans=min(ans,abs(all_value-*ALL));
return ALL;
} int main()
{
//freopen("in.txt","r",stdin);
while(~scanf("%d%d",&n,&m))
{
init();
for(int i=;i<n;i++) {scanf("%d",&val[i]);all_value+=val[i];}
while(m--)
{
int u, v;
scanf("%d%d",&u,&v);
addEdge(u,v);
addEdge(v,u);
}
for(int i=;i<n;i++)
if(!pre[i]) Tarjan(i,-); if(scc==) {puts("impossible");continue;}
for(int u=;u<n;u++)
{
for(int i=head[u];i!=-;i=e[i].next)
{
int v=e[i].v;
if(eccno[u]!=eccno[v]) addEdge2(eccno[u],eccno[v]);
}
}
ans=INF;
dp(,-);
printf("%d\n",ans);
}
return ;
}

HDU 2242 考研路茫茫——空调教室(边双连通分量+树形dp+重边标号)的更多相关文章

  1. HDU 2242 考研路茫茫—空调教室 (边双连通+树形DP)

    <题目链接> 题目大意: 给定一个连通图,每个点有点权,现在需要删除一条边,使得整张图分成两个连通块,问你删除这条边后,两联通块点权值和差值最小是多少. 解题分析: 删除一条边,使原连通图 ...

  2. HDU 2242 考研路茫茫——空调教室 无向图缩环+树形DP

    考研路茫茫——空调教室 Problem Description 众所周知,HDU的考研教室是没有空调的,于是就苦了不少不去图书馆的考研仔们.Lele也是其中一个.而某教室旁边又摆着两个未装上的空调,更 ...

  3. HDU 2242 考研路茫茫——空调教室(边双连通)

    HDU 2242 考研路茫茫--空调教室 题目链接 思路:求边双连通分量.然后进行缩点,点权为双连通分支的点权之和,缩点完变成一棵树,然后在树上dfs一遍就能得出答案 代码: #include < ...

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

    考研路茫茫——空调教室 http://acm.hdu.edu.cn/showproblem.php?pid=2242 分析: 树形dp,删边. 代码: #include<cstdio> # ...

  5. HDU 2242 考研路茫茫----空调教室

    传送门 考研路茫茫——空调教室 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  6. 【HDOJ】2242 考研路茫茫——空调教室

    tarjan缩点,然后树形dp一下可解.重点是重边的处理. /* 2242 */ #include <iostream> #include <sstream> #include ...

  7. HDU2242 考研路茫茫——空调教室 (双联通分+树形DP)

    考研路茫茫——空调教室 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  8. HDU 2242 双连通分量 考研路茫茫——空调教室

    思路就是求边双连通分量,然后缩点,再用树形DP搞一下. 代码和求强连通很类似,有点神奇,=_=,慢慢消化吧 #include <cstdio> #include <cstring&g ...

  9. 考研路茫茫——空调教室HDU2242(Tarjan缩点)

    题意:http://acm.hdu.edu.cn/showproblem.php?pid=2242 给你一个图,问你缩完点树上割边的做小绝对值差. 思路: 这题核算起来整整做了我一天(即24个小时)! ...

随机推荐

  1. Scala中的数组和集合操作

    package test /* 1.在scala集合中,Iterable是共同的Trait,Iterable要求继承者实现一些共同的方法,例如元素的遍历 * 2.Array是scala基础的数据结构, ...

  2. Spark Shuffle Write阶段磁盘文件分析

    这篇文章会详细介绍,Sort Based Shuffle Write 阶段是如何进行落磁盘的 流程分析 入口处: org.apache.spark.scheduler.ShuffleMapTask.r ...

  3. spring security积累

    使用数据库管理用户权限: Spring Security默认情况下需要两张表,用户表和权限表 create table users( username varchar_ignorecase(50) n ...

  4. 7.9 Models -- Connection to An HTTP Server

    一.概述 1. 如果你的Ember应用程序需要从一个HTTP服务器加载JSON数据,在你的服务器返回的任何格式中,配置Ember Data的过程将会加载records. 2. store使用一个被称为 ...

  5. BootStrap的布局学习

    布局组件无数可复用的组件,包括字体图标.下拉菜单.导航.警告框.弹出框等更多功能. Bootstrap的使用非常灵活,可以对各种组件进行合并使用(如:为标签页项 添加带下拉菜单),下面的知识点中将逐个 ...

  6. linux常用命令:vmstat 命令

    vmstat 是Virtual Meomory Statistics(虚拟内存统计)的缩写,可对操作系统的虚拟内存.进程.CPU活动进行监控.他是对系统的整体 情况进行统计,不足之处是无法对某个进程进 ...

  7. python webdriver firefox 登录126邮箱,先添加联系人,然后进入首页发送邮件,带附件。

    代码:#encoding=utf-8from selenium import webdriverfrom selenium.webdriver.common.keys import Keysfrom ...

  8. Linux服务器配置---ssh配置

    Ssh配置     通过配置文件,我们可以有效的管理ssh 1.空闲时间关闭连接 1)修改配置文件“/etc/ssh/sshd_config”,设置clientAliveInterval和client ...

  9. mysql中join后on、where的区别

    SELECT * FROM A; SELECT * FROM B; 以上是两张表的机构 SELECT * FROM A LEFT JOIN B ON A.id=b.a_id ; ; ; 两个语句查询出 ...

  10. 访问Hsql .data数据库文件

    一.Hsql简介: hsql数据库是一款纯Java编写的免费数据库,许可是BSD-style的协议. 仅一个hsqldb.jar文件就包括了数据库引擎,数据库驱动,还有其他用户界面操作等内容.下载地址 ...