题意如标题所述,

先无向图缩点,统计出每个bcc权,建新图,然后一遍dfs生成树,标记出每个点(新图)以及其子孙的权值之和。这样之后就可以dfs2来枚举边(原图的桥),更新最小即可。

调试了半天!原来是建老图时候链式前向星和新图的vector<vector< int>>俩种存图搞乱了!!!不可原谅!哎!愚蠢!愚不可及!提交后1A。

后来百度之后,发现说是用树形dp,看了代码解法,竟然和我的是一样的算法。。原来这种算法可以叫树形dp。。。的确有点dp味道。。不过感觉不太浓。。

以后多个图,多种储存方式要分清!e[i][j]!!!e[u][i]\e[j][1]。。。

#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<cstring>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxv=10010,maxe=50000;
int head[maxv];int nume=0;int e[maxe][2];
void inline adde(int i,int j)
{
e[nume][0]=j;e[nume][1]=head[i];head[i]=nume++;
e[nume][0]=i;e[nume][1]=head[j];head[j]=nume++;
}
int dfn[maxv];int low[maxv];int vis[maxv];int bcc[maxv];int ins[maxv];stack<int>sta;
int times=0; int numb=0; int vise[maxe];
int wi[maxv]; int sumwi[maxv];
void tarjan(int u)
{
dfn[u]=low[u]=times++;
ins[u]=1;
sta.push(u);
for(int i=head[u];i!=-1;i=e[i][1])
{
if(vise[i])continue;
int v=e[i][0];
if(!vis[v])
{
vis[v]=1;
vise[i]=vise[i^1]=1;
tarjan(v);
if(low[v]<low[u])low[u]=low[v];
}
else if(ins[v]&&dfn[v]<low[u])
low[u]=dfn[v];
}
if(low[u]==dfn[u])
{
numb++;
int cur;
do{
cur=sta.top();
sta.pop();
ins[cur]=0;
bcc[cur]=numb;
sumwi[numb]+=wi[cur];
}while(cur!=u);
}
}
vector<vector<int> >e2(maxv+1);
int n,m; int mindis=inf;
int getabs(int x)
{
return x<0?-x:x;
}
void init()
{
numb=times=nume=0;mindis=inf;
memset(vise,0,sizeof(vise));
for(int i=0;i<maxv;i++)
{
sumwi[i]=wi[i]=bcc[i]=ins[i]=dfn[i]=low[i]=vis[i]=0;
e2[i].clear(); head[i]=-1;
}
}
int dfs(int u) //获得sumwi【i】:子孙包括自己的权值和
{
for(int i=0;i<e2[u].size();i++)
{
int v=e2[u][i];
if(!vis[v])
{
vis[v]=1;
sumwi[u]+=dfs(v);
}
}
return sumwi[u];
}
void dfs2(int u)
{
for(int i=0;i<e2[u].size();i++)
{
int v=e2[u][i];
if(!vis[v])
{
if(getabs(sumwi[1]-sumwi[v]-sumwi[v])<mindis)
{
mindis=getabs(sumwi[1]-sumwi[v]-sumwi[v]);
}
vis[v]=1;
dfs2(v);
}
}
}
void solve()
{
vis[0]=1;
tarjan(0);
if(numb==1)
{
printf("impossible\n");
return ;
}
memset(vise,0,sizeof(vise));
for(int i=0;i<n;i++)
for(int j=head[i];j!=-1;j=e[j][1])
if(bcc[i]!=bcc[e[j][0]]&&vise[j]==0)
{
e2[bcc[i]].push_back(bcc[e[j][0]]);
e2[bcc[e[j][0]]].push_back(bcc[i]);
vise[j]=vise[j^1]=1;
}
memset(vis,0,sizeof(vis));
vis[1]=1;
dfs(1);
memset(vis,0,sizeof(vis));
vis[1]=1;
dfs2(1);
printf("%d\n",mindis);
}
void readin()
{
for(int i=0;i<n;i++)
scanf("%d",&wi[i]);
int aa,bb;
for(int i=0;i<m;i++)
{
scanf("%d%d",&aa,&bb);
adde(aa,bb);
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
init();
readin();
solve();
}
return 0;
}

hdu 2242 无向图/求用桥一分为二后使俩个bcc点权值和之差最小并输出 /缩点+2次新图dfs的更多相关文章

  1. HDU 4738——Caocao's Bridges——————【求割边/桥的最小权值】

     Caocao's Bridges Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

  2. HDU 2242 考研路茫茫—空调教室 (边双连通+树形DP)

    <题目链接> 题目大意: 给定一个连通图,每个点有点权,现在需要删除一条边,使得整张图分成两个连通块,问你删除这条边后,两联通块点权值和差值最小是多少. 解题分析: 删除一条边,使原连通图 ...

  3. Hdu 4738【求无向图的桥】.cpp

    题目: 曹操在长江上建立了一些点,点之间有一些边连着.如果这些点构成的无向图变成了连通图,那么曹操就无敌了.刘备为了防止曹操变得无敌,就打算去摧毁连接曹操的点的桥.但是诸葛亮把所有炸弹都带走了,只留下 ...

  4. hdu4612 无向图中随意加入一条边后使桥的数量最少 / 无向图缩点+求树的直径

    题意如上,含有重边(重边的话,俩个点就能够构成了边双连通). 先缩点成树,在求数的直径,最远的连起来,剩下边(桥)的自然最少.这里学习了树的直径求法:第一次选随意起点U,进行bfs,到达最远的一个点v ...

  5. hdu4612 无向图中任意添加一条边后使桥的数量最少 / 无向图缩点+求树的直径

    题意如上,含有重边(重边的话,俩个点就可以构成了边双连通). 先缩点成树,在求数的直径,最远的连起来,剩下边(桥)的自然最少.这里学习了树的直径求法:第一次选任意起点U,进行bfs,到达最远的一个点v ...

  6. HDU 4738--Caocao's Bridges(重边无向图求桥)

    Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  7. UVA 796 Critical Links(无向图求桥)

    题目大意:给你一个网络要求这里面的桥. 输入数据: n 个点 点的编号  (与这个点相连的点的个数m)  依次是m个点的   输入到文件结束. 桥输出的时候需要排序   知识汇总: 桥:   无向连通 ...

  8. 【并查集缩点+tarjan无向图求桥】Where are you @牛客练习赛32 D

    目录 [并查集缩点+tarjan无向图求桥]Where are you @牛客练习赛32 D PROBLEM SOLUTION CODE [并查集缩点+tarjan无向图求桥]Where are yo ...

  9. UVA 796 Critical Links(模板题)(无向图求桥)

    <题目链接> 题目大意: 无向连通图求桥,并将桥按顺序输出. 解题分析: 无向图求桥的模板题,下面用了kuangbin的模板. #include <cstdio> #inclu ...

随机推荐

  1. (新手)使用pandas操作EXCEL

    import pandas as pdimport numpy as npfrom pandas import DataFrame,Series#path = r'C:\Users\tsl\Deskt ...

  2. Python9-IO模型-day41

    # 进程:启动多个进程,进程之间是由操作系统负责调用# 线程:启动多个线程,真正由被cpu执行的最小单位实际是线程# 开启一个线程,创建一个线程,寄存器.堆栈# 关闭一个线程# 协程# 本质上是一个线 ...

  3. mysql同步故障解决

    故障现象:Slave_SQL_Running: No Slave状态:mysql> show slave status\GSlave_IO_Running: YesSlave_SQL_Runni ...

  4. 使用FileSystem类进行文件读写及查看文件信息

    使用FileSystem类进行文件读写及查看文件信息   在这一节我们要深入了解Hadoop的FileSystem类——这是与与hadoop的文件系统交互的重要接口.虽然我们只是着重于HDFS的实现, ...

  5. Android Kotlin适用小函数

    都是一些Android适用的Kotlin小函数. 1.点击空白隐藏键盘 //点击空白隐藏键盘 override fun onTouchEvent(event: MotionEvent): Boolea ...

  6. springboot(七):springboot+mybatis多数据源最简解决方案

    说起多数据源,一般都来解决那些问题呢,主从模式或者业务比较复杂需要连接不同的分库来支持业务.我们项目是后者的模式,网上找了很多,大都是根据jpa来做多数据源解决方案,要不就是老的spring多数据源解 ...

  7. Asp.net自定义控件开发任我行(8)-数据集绑定

    摘要 已经有好几天没有写博客了,今天继续,前几天写到了注册自定义事件,今天我们来讲数据集绑定. 先把运行效果截个图给大家看,让大家心里也有个底.(大家要从第一章开始看起,我们每一章都是接着前面没做完的 ...

  8. 可拖动jquery插件

    http://www.open-open.com/ajax/DragDrop.htm http://sc.chinaz.com/info/130722592854.htm http://sc.itcn ...

  9. 纯js国际化(i18n)

    i18n,是internationalization单词的简写,中间18个字符略去,简称i18n,意图就是实现国际化,方便产品在不同的场景下使用 目标:可以点击切换语言或者ChangeLanguage ...

  10. 【Luogu P3371&P4779】【模板】单源最短路径(线段树优化Dijkstra)

    线段树优化$\rm dijkstra$ 线段树每个节点维护$[l,r]$中$dist$最小的点,删除则把该点$dist$赋值为$+\infty$,然后更新该点影响到的线段树上的其他节点即可. 可以得到 ...