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. POJ3096:Surprising Strings(map)

    http://poj.org/problem?id=3096 for循环真是奇妙! #include <string.h> #include <stdio.h> #includ ...

  2. 搭建私有yum仓库

    需要工具: centos7 nginx rsync 新建文件夹存放镜像数据 mkdir /data mkdir /data/yum_data 同步数据 国内开源镜像站没有几个支持rsync,科技大学的 ...

  3. C#集合中的Add与AddRange方法

    C#.NET的集合主要位于System.Collections和System.Collections.Generic(泛型)这两个namespace中. 1.System.Collections 比如 ...

  4. python3中pymysql模块安装及连接数据库(同‘python安装HTMLTestRunner’)

    https://pypi.org/project/PyMySQL/#files 安装完成之后就是连接数据库了 机器上安装了mysql的数据库,并且已经创建了两张表用于测试 python3连接数据库及删 ...

  5. iOS 网易彩票-2框架搭建-代码重构

    在上一篇中,我们基本已经把整个框架都搭建出来了,下面进行代码重构一下. 思路: 导航按钮,按下时,会变灰,那是系统自带了,通过自定义UIButton,实现按下按钮立即切换效果. MJTabBarCon ...

  6. C#在splitContainer1控件和panel控件中显示窗体

    现在有两个窗体 Form1 和Form2 Form1中有控件splitContainer1 和panel .控件.我们希望Form2在splitContainer1或者panel控件中显示 1:首先看 ...

  7. qt mysql驱动问题解绝

    传统解决方法:一.解决问题 本文解决在Ubuntu16.04系统下,Qt5无法连接MySQL数据库的问题(Qt5缺少MySQL驱动,Qt5缺少libqsqlmysql.so动态库,如何安装libqsq ...

  8. Oracle 错误代码小结

    ORA-00001: 违反唯一约束条件 (.) ORA-00017: 请求会话以设置跟踪事件 ORA-00018: 超出最大会话数 ORA-00019: 超出最大会话许可数 ORA-00020: 超出 ...

  9. Python: translate()审查清理文本字符串

    ①凌乱的字符串如下: ②创建一个小的转换表格然后使用translate()方法 空白字符\t和\f已经被重新映射到一个空格. \r直接被删除 ③构建一个更大的表格,删除所有的和音符

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

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