hdu 2242双联通分量+树形dp
- /*先求出双联通缩点,然后进行树形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的更多相关文章
- HDU 2242 连通分量缩点+树形dp
题目大意是: 所有点在一个连通图上,希望去掉一条边得到两个连通图,且两个图上所有点的权值的差最小,如果没有割边,则输出impossible 这道题需要先利用tarjan算法将在同一连通分量中的点缩成一 ...
- 『Tarjan算法 无向图的双联通分量』
无向图的双连通分量 定义:若一张无向连通图不存在割点,则称它为"点双连通图".若一张无向连通图不存在割边,则称它为"边双连通图". 无向图图的极大点双连通子图被 ...
- HDU4612 Warm up —— 边双联通分量 + 重边 + 缩点 + 树上最长路
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=4612 Warm up Time Limit: 10000/5000 MS (Java/Ot ...
- 【UVA10972】RevolC FaeLoN (求边双联通分量)
题意: 给你一个无向图,要求把所有无向边改成有向边,并且添加最少的有向边,使得新的有向图强联通. 分析: 这题的解法还是很好想的.先用边双联通分量缩点,然后找新图中入度为0和为1的点,入度为0则ans ...
- lightoj 1300 边双联通分量+交叉染色求奇圈
题目链接:http://lightoj.com/volume_showproblem.php?problem=1300 边双连通分量首先dfs找出桥并标记,然后dfs交叉着色找奇圈上的点.这题只要求在 ...
- HDU5409---CRB and Graph 2015多校 双联通分量缩点
题意:一个联通的无向图, 对于每一条边, 若删除该边后存在两点不可达,则输出这两个点, 如果存在多个则输出第一个点尽可能大,第二个点尽可能小的. 不存在输出0 0 首先 若删除某一条边后存在多个联通分 ...
- poj2942(双联通分量,交叉染色判二分图)
题意:一些骑士,他们有些人之间有矛盾,现在要求选出一些骑士围成一圈,圈要满足如下条件:1.人数大于1.2.总人数为奇数.3.有仇恨的骑士不能挨着坐.问有几个骑士不能和任何人形成任何的圆圈. 思路:首先 ...
- hdu 4514 并查集+树形dp
湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Tot ...
- 大白书中无向图的点双联通分量(BCC)模板的分析与理解
对于一个无向图,如果任意两点至少存在两条点不重复(除起点和终点外无公共点)的路径,则这个图就是点双联通. 这个要求等价于任意两条边都存在于一个简单环(即同一个点不能在圈中出现两次)中,即内部无割点. ...
随机推荐
- JSP-Runoob:JSP 异常处理
ylbtech-JSP-Runoob:JSP 异常处理 1.返回顶部 1. JSP 异常处理 当编写JSP程序的时候,程序员可能会遗漏一些BUG,这些BUG可能会出现在程序的任何地方.JSP代码中通常 ...
- win10系统下,开启数据库远程连接方式
右键左下角的windows标志,选择控制面板 2.查看方式修改为大图标 3.选择高级设置 4.新建入站规则 5.选择端口然后下一步 6.选择tcp协议,端口输入80,3306 7.选择允许连接 8.规 ...
- Mac 终端执行JavaScript
创建: 2017/09/16 第一步 打开命令 输入alias jsc="/System/Library/Frameworks/JavaScriptCore.framework/ ...
- Linux系统的整体目录结构和文件解析
Linux系统目录结构 使用 ls / 查看系统的文件目录: /:根目录,根目录下一般只存放子目录,不存放文件.在linux系统中所有的文件都挂载该目录下. /bin:命令目录. 存放系统的可执行的二 ...
- nginx + php-fpm 运行原理
一.关于nginx 1.1 简单认知 我们都知道nginx 是web服务器. 也知道 用户访问时通过ip和端口访问 nginx. 那么nginx 是如何 通过php 获取数据并返回数据的呢? 1.2 ...
- linux top 的用法
本篇博文主要讲解有关top命令,top命令的主要功能是查看进程活动状态以及一些系统状况. TOP是一个动态显示过程,即可以通过用户按键来不断刷新当前状态.如果在前台执行该命令,它将独占前台,直到用户终 ...
- Sublime Text2安装emmet
一.安装Package Control 如果Preferences中没有Package Control,需要手动安装.安装方法如下: 访问Package Controls站点复制一段python命令安 ...
- [ JSOI 2015 ] Salesman
\(\\\) \(Description\) 给出一棵以\(1\)为根的\(N\)个节点的树,开始的时候你在\(1\)号节点. 除了\(1\)号节点以外,每个点都有访问次数限制\(t_i\),即到达该 ...
- (转)在 vue-cli 脚手架中引用 jQuery、bootstrap 以及使用 sass、less 编写 css [vue-cli配置入门]
写在前面: 本文是vue-手摸手教你使用vue-cli脚手架-详细步骤图文解析之后,又一篇关于vue-cli脚手架配置相关的文章,因为有些文章步骤不够清晰,当时我引入JQuery.bootstrap的 ...
- js 翻页
翻页功能是js很基础的一个算法,且用得很多,所以必须掌握此项技能. 我们要想清楚在实现翻页的过程中需要哪几个步骤: 1.我们首先需要的变量有哪些,必须的有一个存放当前页码的变量nowPage.一个存放 ...