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. Windows下pycharm使用theano的方法

    安装theano前需要自行安装Anaconda和PyCharm.在网上查了在PyCharm上安装theano的方法,但是均遇到了一些问题,现将问题与解决方案介绍如下. (一)第一种安装方式 打开cmd ...

  2. 使用浏览器,调试js代码

    1:创建html网页和js文件 <!doctype html> <html> <head> <meta charset="utf-8"&g ...

  3. logstash的各个场景应用(配置文件均已实践过)

    场景: 1) datasource->logstash->elasticsearch->kibana 2) datasource->filebeat->logstash- ...

  4. test examples/test scripts

    //https://www.getpostman.com/docs/v6/postman/scripts/test_examples //Setting an environment variable ...

  5. pd.read_csv操作读取分隔符csv和text文件

    pandas.read_csv可以读取CSV(逗号分割)文件.文本类型的文件text.log类型到DataFrame 1. pandas.read_csv常用参数整理 也支持文件的部分导入和选择迭代 ...

  6. 关于在ASP.NET中使用JavaScript的建议

    一个很恼人的情况,就是当你使用JS在一个ASP,NET应用程序中引用一个在模板页初始化的服务器控件的时候: 比如,我们在模板页有一个TextBox的服务器控件,而且我们想要去获取他的Text:如果你使 ...

  7. P2503 [HAOI2006]均分数据

    P2503 [HAOI2006]均分数据 模拟退火+dp (不得不说,我今天欧气爆棚) 随机出1个数列,然后跑一遍dp统计 #include<iostream> #include<c ...

  8. 20145104张家明 《Java程序设计》第10周学习总结

    20145104张家明 <Java程序设计>第10周学习总结 教材学习内容总结 网络编程 网络编程就是两个或多个设备(程序)之间的数据交换. 识别网络上的每个设备:①IP地址②域名(Dom ...

  9. 20145122《 Java网络编程》实验五实验报告

    实验名称 Java网络编程 实验内容 1.掌握Socket程序的编写: 2.掌握密码技术的使用: 3.设计安全传输系统. 结对小伙伴 20145120黄玄曦 博客地址:http://www.cnblo ...

  10. 20145204《网络对抗》逆向及bof基础实践

    20145204<网络对抗>逆向及bof基础实践 实践目的说明 实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何 ...