/*先求出双联通缩点,然后进行树形dp*/
#include<stdio.h>
#include<string.h>
#include<math.h>
#define inf 0x3fffffff
#define N 11000
struct node
{
int u,v,next;
} bian[N*4],edge[N*4];
int head[N],yong,dfn[N],low[N],index,f[N*4],cnt,n,num[N];
int yon;
int belong[N],tot[N];
int visit[N],dp[N];
void init()
{
memset(head,-1,sizeof(head));
yong=0;
index=0;
cnt=0;
memset(dfn,0,sizeof(dfn));
memset(f,0,sizeof(f));
memset(low,0,sizeof(low));
}
int Min(int a,int b)
{
return a>b?b:a;
}
void addedge(int u,int v) //一次建图
{
bian[yong].u=u;
bian[yong].v=v;
bian[yong].next=head[u];
head[u]=yong++;
}
void tarjan(int u,int pre ) //tarjan算法求桥
{
dfn[u]=low[u]=++index;
int i;
for(i=head[u]; i!=-1; i=bian[i].next)
{
int v=bian[i].v;
if(i==(pre^1))continue;
if(!dfn[v])
{
tarjan(v,i);
low[u]=Min(low[u],low[v]);
if(low[v]>dfn[u])
{
cnt=1;//是否存在桥
f[i]=f[i^1]=1;//标记桥
}
}
else
low[u]=Min(low[u],dfn[v]);
}
return ;
}
void dfs(int u,int pre)
{
belong[u]=cnt;//缩
tot[cnt]+=num[u];//记录缩点的权值
int i,v;
for(i=head[u]; i!=-1; i=bian[i].next)
{
v=bian[i].v;
if(!f[i]&&!belong[v]&&i!=(pre^1))
dfs(v,i);
}
return ;
}
void addedge1(int u,int v) //二次建图
{
edge[yon].u=u;
edge[yon].v=v;
edge[yon].next=head[u];
head[u]=yon++;
}
void slove()
{
int i;
memset(belong,0,sizeof(belong));
memset(tot,0,sizeof(tot));
cnt=0;
for(i=1; i<=n; i++)
if(!belong[i]) //缩点
{
cnt++;
dfs(i,-1);
}
memset(head,-1,sizeof(head));
yon=0;
for(i=0; i<yong; i++) //重新建图
{
int u=bian[i].u,v=bian[i].v;
if(belong[u]!=belong[v])
{
addedge1(belong[u],belong[v]);
addedge1(belong[v],belong[u]);
// printf("%d %d\n",belong[u],belong[v]);
}
}
return ;
} int dfs1(int u) //为树形图求出他和他的子节点的权值
{
visit[u]=1;
int i,v,sum=0;
sum+=tot[u];
for(i=head[u]; i!=-1; i=edge[i].next)
{
v=edge[i].v;
if(!visit[v])
{
sum+=dfs1(v);
}
}
//printf("%d %d\n",u,sum);
dp[u]=sum;
return sum;
}
int main()
{
int m,i,j,k,a,b,c,sum,minn;
while(scanf("%d%d",&n,&m)!=EOF)
{
sum=0;
init();
for(i=1; i<=n; i++)
{
scanf("%d",&num[i]);
sum+=num[i];
}
while(m--)
{
scanf("%d%d",&a,&b);
a++;
b++;
addedge(a,b);
addedge(b,a);
}
tarjan(1,-1);
if(cnt==0) //如果不存在桥
{
printf("impossible\n");
continue;
}
slove();
memset(visit,0,sizeof(visit));
dfs1(1);
minn=inf;
for(i=1; i<=cnt; i++)
{
// printf("%d\n",dp[i]);
minn=Min(minn,fabs(sum*1.0-2.0*dp[i]));//求最优
}
printf("%d\n",minn);
}
return 0;
}

hdu 2242双联通分量+树形dp的更多相关文章

  1. HDU 2242 连通分量缩点+树形dp

    题目大意是: 所有点在一个连通图上,希望去掉一条边得到两个连通图,且两个图上所有点的权值的差最小,如果没有割边,则输出impossible 这道题需要先利用tarjan算法将在同一连通分量中的点缩成一 ...

  2. 『Tarjan算法 无向图的双联通分量』

    无向图的双连通分量 定义:若一张无向连通图不存在割点,则称它为"点双连通图".若一张无向连通图不存在割边,则称它为"边双连通图". 无向图图的极大点双连通子图被 ...

  3. HDU4612 Warm up —— 边双联通分量 + 重边 + 缩点 + 树上最长路

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=4612 Warm up Time Limit: 10000/5000 MS (Java/Ot ...

  4. 【UVA10972】RevolC FaeLoN (求边双联通分量)

    题意: 给你一个无向图,要求把所有无向边改成有向边,并且添加最少的有向边,使得新的有向图强联通. 分析: 这题的解法还是很好想的.先用边双联通分量缩点,然后找新图中入度为0和为1的点,入度为0则ans ...

  5. lightoj 1300 边双联通分量+交叉染色求奇圈

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1300 边双连通分量首先dfs找出桥并标记,然后dfs交叉着色找奇圈上的点.这题只要求在 ...

  6. HDU5409---CRB and Graph 2015多校 双联通分量缩点

    题意:一个联通的无向图, 对于每一条边, 若删除该边后存在两点不可达,则输出这两个点, 如果存在多个则输出第一个点尽可能大,第二个点尽可能小的. 不存在输出0 0 首先 若删除某一条边后存在多个联通分 ...

  7. poj2942(双联通分量,交叉染色判二分图)

    题意:一些骑士,他们有些人之间有矛盾,现在要求选出一些骑士围成一圈,圈要满足如下条件:1.人数大于1.2.总人数为奇数.3.有仇恨的骑士不能挨着坐.问有几个骑士不能和任何人形成任何的圆圈. 思路:首先 ...

  8. hdu 4514 并查集+树形dp

    湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Tot ...

  9. 大白书中无向图的点双联通分量(BCC)模板的分析与理解

    对于一个无向图,如果任意两点至少存在两条点不重复(除起点和终点外无公共点)的路径,则这个图就是点双联通. 这个要求等价于任意两条边都存在于一个简单环(即同一个点不能在圈中出现两次)中,即内部无割点. ...

随机推荐

  1. 39. Ext.data.SimpleStore的使用方法

    转自:https://www.cnblogs.com/bluestorm/archive/2013/06/14/3135361.html 新版4.2的extjs已经废弃了simpleStore --& ...

  2. bzoj4563: [Haoi2016]放棋子(错排+高精)

    4563: [Haoi2016]放棋子 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 387  Solved: 247[Submit][Status] ...

  3. [jzoj NOIP2018模拟10.23]

    丢分主要是下面几个方面: 1.T2代码交错了,有个特判没写丢了10分 2.T1线段树加等差数列写错了(其实二维差分就可以,但我当时不会) 3.T3思考再三还是为了10分写上了主席树,还是写错了 总体评 ...

  4. Android布局属性LayoutParams的理解

    在一次笔试中搞混LayoutParams的用法,特来总结一番: LayoutParams继承于Android.View.ViewGroup.LayoutParams.LayoutParams相当于一个 ...

  5. Elasticsearch之CURL命令的GET

    这是个查询命令. 前期博客 Elasticsearch之CURL命令的PUT和POST对比 1. 以上是根据员工id查询. 即在任意的查询字符串中添加pretty参数,es可以得到易于我们识别的jso ...

  6. Java中的异常注意点

    在java中 使用throw关键字抛出异常       使用throws关键字声明异常 public static void main(String[] args) throws Exception{ ...

  7. 实现div毛玻璃背景

    毛玻璃效果 ios里毛玻璃效果的使用非常多,本文介绍一个实现div毛玻璃背景的方法 CSS3 Filter CSS3的Filter主要用在图像的特效处理上,默认值为none,还有以下备选项:   1. ...

  8. js中添加node.js语法支持

    File——>settings

  9. Hive扩展功能(四)--HiveServer2服务

    软件环境: linux系统: CentOS6.7 Hadoop版本: 2.6.5 zookeeper版本: 3.4.8 主机配置: 一共m1, m2, m3这五部机, 每部主机的用户名都为centos ...

  10. jQuery——表格添加数据

    1.遮罩层宽高100%,position,不占位 2.注册a标签的删除事件,用on()方法,以方法可以动态添加,之前js需要利用冒泡属性(父标签注册事件,子标签冒泡,target===li触发事件) ...