hdu2242(树形dp+tarjan+缩点)
hdu2242 http://acm.hdu.edu.cn/showproblem.php?pid=2242
给定n,m表示n个点,m条边
每个点有个权值
问我们删除两某条边(割边)后将图分为两个部分,要使得两个部分的权值之差最小
这题的弱化版本是在一棵树上删除某条边后后将图分为两个部分,要使得两个部分的权值之差最小。是用树形dp来做的
但是这道题目是个图,但是我们可以转化为树,即将图中的边连通分量求出来,然后缩成一个点,建出一个新的树图,那么就可以用树形dp来求解题目了.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <math.h>
using namespace std;
typedef long long LL;
const int INF = <<;
const int N = + ;
vector<int> g1[N],g2[N];
int val1[N],val2[N];
int dfn[N],low[N],dfs_clock,cnt;
int belong[N];
stack<int> st;
bool vis[N];
int ans,sum;
void tarjan(int u, int fa)
{
bool flag = false;
vis[u] = true;
dfn[u] = low[u] = ++dfs_clock;
st.push(u);
for(int i=; i<g1[u].size(); ++i)
{ int v = g1[u][i];
if(v==fa && !flag)
{
flag = true;
continue;
}
if(!vis[v]) tarjan(v,u);
low[u] = min(low[u],low[v]);
}
if(dfn[u]==low[u])
{
cnt++;
int x;
do
{
x= st.top();
st.pop();
belong[x] = cnt;
val2[cnt] += val1[x];
}while(u!=x);
}
} void dfs(int u, int fa)
{
vis[u] = true;
for(int i=; i<g2[u].size(); ++i)
{
int v = g2[u][i];
if(vis[v]) continue;
dfs(v,u);
val2[u] += val2[v];
}
}
void dfs2(int u, int fa)
{
vis[u] = true;
for(int i=; i<g2[u].size(); ++i)
{
int v = g2[u][i];
if(vis[v]) continue;
ans = min(ans,abs(sum-*val2[v]));
dfs2(v,u);
}
}
int main()
{
int n,m,i,u,v,j;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=; i<=n; ++i)
{
g1[i].clear();
g2[i].clear();
}
sum = ;
for(i=; i<n; ++i)
{
scanf("%d",&val1[i]);
sum += val1[i];
}
for(i=; i<m; ++i)
{
scanf("%d%d",&u,&v);
g1[u].push_back(v);
g1[v].push_back(u);
}
memset(vis,,sizeof(vis));
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(val2,,sizeof(val2));
dfs_clock = ;
cnt = ;
tarjan(,-);
for(i=; i<n; ++i)
for(j=; j<g1[i].size(); ++j)
{
int v = g1[i][j];
if(belong[v] != belong[i])//建新图,虽然新建的图会有重边,但是不影响树形dp
{
g2[belong[i]].push_back(belong[v]);
g2[belong[v]].push_back(belong[i]);
}
}
if(cnt==)//如果整个图是边连通的,那么不管删哪条边都不能使得图不连通
{
puts("impossible");
continue;
}
ans = INF;
memset(vis,,sizeof(vis));
dfs(,-);
memset(vis,,sizeof(vis));
dfs2(,-);
printf("%d\n",ans);
}
return ;
}
hdu2242(树形dp+tarjan+缩点)的更多相关文章
- 软件安装:树上分组DP/tarjan缩点/(也许基环树?)
提炼:tarjan环缩成点,建0虚根,跑树形DP,最难的是看出可能有n个点n条边然后缩点,n个点n条边可能不只有一个环 n个点n条边->基环树: 基环树,也是环套树,简单地讲就是树上在加一条边. ...
- 洛谷P2515 [HAOI2010]软件安装(tarjan缩点+树形dp)
传送门 我们可以把每一个$d$看做它的父亲,这样这个东西就构成了一个树形结构 问题是他有可能形成环,所以我们还需要一遍tarjan缩点 缩完点后从0向所有入度为零的点连边 然后再跑一下树形dp就行了 ...
- BZOJ 2427 /HAOI 2010 软件安装 tarjan缩点+树形DP
终于是道中文题了.... 当时考试的时候就考的这道题.... 果断GG. 思路: 因为有可能存在依赖环,所以呢 先要tarjan一遍 来缩点. 随后就进行一遍树形DP就好了.. x表示当前的节点.j表 ...
- HDU4612(Warm up)2013多校2-图的边双连通问题(Tarjan算法+树形DP)
/** 题目大意: 给你一个无向连通图,问加上一条边后得到的图的最少的割边数; 算法思想: 图的边双连通Tarjan算法+树形DP; 即通过Tarjan算法对边双连通缩图,构成一棵树,然后用树形DP求 ...
- 洛谷 P2515 [HAOI2010]软件安装(缩点+树形dp)
题面 luogu 题解 缩点+树形dp 依赖关系可以看作有向边 因为有环,先缩点 缩点后,有可能图不联通. 我们可以新建一个结点连接每个联通块. 然后就是树形dp了 Code #include< ...
- [HAOI2010]软件安装(树形背包,tarjan缩点)
题目描述 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大). 但是 ...
- 硬币问题 tarjan缩点+DP 莫涛
2013-09-15 20:04 题目描述 有这样一个游戏,桌面上摆了N枚硬币,分别标号1-N,每枚硬币有一个分数C[i]与一个后继硬币T[i].作为游戏参与者的你,可以购买一个名为mlj的小机器人, ...
- Tarjan+树形DP【洛谷P2515】[HAOI2010]软件安装
[洛谷P2515][HAOI2010]软件安装 题目描述 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得 ...
- 【BZOJ2427】[HAOI2010] 软件安装(缩点+树形DP)
点此看题面 大致题意: 有\(N\)个软件,每个软件有至多一个依赖以及一个所占空间大小\(W_i\),只有当一个软件的直接依赖和所有的间接依赖都安装了,它才能正常工作并造成\(V_i\)的价值.求在容 ...
随机推荐
- [Codecademy] HTML&CSS 第一课:HTML Basic
本文出自 http://blog.csdn.net/shuangde800 ------------------------------------------------------------ ...
- JAVA中IO和NIO的详解分析,内容来自网络和自己总结
用一个例子来阐释: 一辆客车上有10个乘客,他们的目的地各不相同,当没有售票员的时候,司机就需要不断的询问每一站是否有乘客需要下车,需要则停下,不需要则继续开车,这种就是阻塞的方式. 当有售票员的时候 ...
- 【老鸟学算法】包含 min函数的栈设计——java实现
要求: 1. 定义栈的数据结构,要求添加一个 min函数,能够得到栈的最小元素. 2. 要求函数 min.push 以及 pop 的时间复杂度都是 O(1). 这是考验“栈”数据结构设计.众所周知,栈 ...
- ExtJs4 笔记(10) Ext.tab.Panel 选项卡
本篇讲解选项卡控件. 一.基本选项卡 首先我们来定义一个基本的选项卡控件,其中每个Tab各有不同,Tab的正文内容可以有三种方式获取: 1.基本方式:通过定义html和items的方式. 2.读取其他 ...
- [Android学习笔记]Context简单理解
一.Context是什么?上下文对象,可以理解为一个程序的运行的环境,从中可以获取当前程序的资源:getResources,getAssets 二.常见的Context有哪些?Application ...
- sqlserver 操作技巧
1.将不同库中的一张表数据导入到另外一张表中去 ① 两张表多存在实体,两表的字段相同,字段的顺序相同的话. insert into 表B select * from 表A ② 两张表多存在实体,两表的 ...
- Zxing中文乱码解决方法
Zxing中文乱码解决方法总结 尝试过非常多方法 最后发现此方法解决的乱码最多....... 在百度搜索二维码图片 经过前2页的測试 除开一张图之外 其余都能扫描出结果 假设大家有更好的解决方法 ...
- 重拾linux
重拾linux 起因 因为想重拾起linux,同时需要用docker起几个镜像,用来学习网络知识.本来想直接去阿里云上买,后来一想自己机器上,起一个linux是个不错的选择,毕竟不花钱! 还可以用来做 ...
- [Android学习笔记]SeekBar的使用
一.SeekBar滑动条的使用 xml声明: <SeekBar android:id="@+id/seekbar" android:layout_width="20 ...
- linux内存基础知识和相关调优方案
内存是计算机中重要的部件之中的一个.它是与CPU进行沟通的桥梁. 计算机中全部程序的执行都是在内存中进行的.因此内存的性能对计算机的影响很大.内存作用是用于临时存放CPU中的运算数据,以及与硬盘等外部 ...