HDU 2242 考研路茫茫——空调教室(边双连通分量+树形dp+重边标号)
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+重边标号)的更多相关文章
- HDU 2242 考研路茫茫—空调教室 (边双连通+树形DP)
		
<题目链接> 题目大意: 给定一个连通图,每个点有点权,现在需要删除一条边,使得整张图分成两个连通块,问你删除这条边后,两联通块点权值和差值最小是多少. 解题分析: 删除一条边,使原连通图 ...
 - HDU 2242 考研路茫茫——空调教室 无向图缩环+树形DP
		
考研路茫茫——空调教室 Problem Description 众所周知,HDU的考研教室是没有空调的,于是就苦了不少不去图书馆的考研仔们.Lele也是其中一个.而某教室旁边又摆着两个未装上的空调,更 ...
 - HDU 2242 考研路茫茫——空调教室(边双连通)
		
HDU 2242 考研路茫茫--空调教室 题目链接 思路:求边双连通分量.然后进行缩点,点权为双连通分支的点权之和,缩点完变成一棵树,然后在树上dfs一遍就能得出答案 代码: #include < ...
 - HDU 2242 考研路茫茫——空调教室
		
考研路茫茫——空调教室 http://acm.hdu.edu.cn/showproblem.php?pid=2242 分析: 树形dp,删边. 代码: #include<cstdio> # ...
 - HDU 2242 考研路茫茫----空调教室
		
传送门 考研路茫茫——空调教室 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
 - 【HDOJ】2242 考研路茫茫——空调教室
		
tarjan缩点,然后树形dp一下可解.重点是重边的处理. /* 2242 */ #include <iostream> #include <sstream> #include ...
 - HDU2242 考研路茫茫——空调教室 (双联通分+树形DP)
		
考研路茫茫——空调教室 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
 - HDU 2242 双连通分量 考研路茫茫——空调教室
		
思路就是求边双连通分量,然后缩点,再用树形DP搞一下. 代码和求强连通很类似,有点神奇,=_=,慢慢消化吧 #include <cstdio> #include <cstring&g ...
 - 考研路茫茫——空调教室HDU2242(Tarjan缩点)
		
题意:http://acm.hdu.edu.cn/showproblem.php?pid=2242 给你一个图,问你缩完点树上割边的做小绝对值差. 思路: 这题核算起来整整做了我一天(即24个小时)! ...
 
随机推荐
- mac版 android studio问题解决
			
1.mac安装android studio 解决方案:如果你是安装新手,可以下载androud studio boundls 和 安装环境的jdk就可以了,不需要单独在配置环境了,如果你有经验,可以单 ...
 - BFS广搜题目(转载)
			
BFS广搜题目有时间一个个做下来 2009-12-29 15:09 1574人阅读 评论(1) 收藏 举报 图形graphc优化存储游戏 有时间要去做做这些题目,所以从他人空间copy过来了,谢谢那位 ...
 - Outlier Detection
			
1)正态分布数据,飘出95%的可能是异常值.变量var正态标准化,|var|<=1.96的可能是异常值,further chk needed!large sample better. 对于偏态分 ...
 - CNN实现垃圾邮件分类(行大小不一致要补全)
			
以下是利用卷积神经网络对某一个句子的处理结构图 我们从上图可知,将一句话转化成一个矩阵.我们看到该句话有6个单词和一个标点符号,所以我们可以将该矩阵设置为7行,对于列的话每个单词可以用什么样的数值表示 ...
 - git客户端msysGit和TortoiseGit使用
			
windows下使用TortoiseGit代替Git命令行操作(参考http://www.cnblogs.com/candle806/p/4071656.html) 1.配置TortoiseGit与m ...
 - dedecms开启报错
			
php.ini里面设置display_errors = On 开启错误提示,error_reporting = E_ALL & ~E_NOTICE 设置错误等级.也可以在php文件中ini_s ...
 - Makefile小结
			
Makefile最基本的规则:target....:prerequisites..... command 或:target....:prerequisites.....;command target: ...
 - VS2010/MFC编程入门之五十一(图形图像:GDI对象之画刷CBrush)
			
上一节中鸡啄米主要讲的是画笔CPen的用法,前面也说了,GDI对象中最常用的就是画笔和画刷,本节就讲讲画刷CBrush. 鸡啄米依然是通过实例的方式来说明画刷的用法.此实例要实现的功能是,对话框上有一 ...
 - python在交互模式下直接输入对象后回车,调用的是对象的__repr__()方法,这个方法表示的是一个编码,用print+对象是调用对象的__str__方法
			
交互模式下调用对象的__repr__()方法,这个方法表示的是一个编码 >>> u"国庆节快乐"u'\u56fd\u5e86\u8282\u5feb\u4e50' ...
 - Linux服务器---mysql忘记root密码
			
忘记root密码 如果不小心忘记了root密码,那么mysql就不能再登录了,这时就要重置root密码才行.通过下面的步骤,我们可以重新设置root密码. 1.退出mysql [root@localh ...