hdu_2242

题目大意:求将一张无向图(n个点,m条边)移除一条边分为不连通两部分,使得两部分的点权和最接近,若无法分为两部分,则输出impossible。

题解:拿到题面还算清晰,就是先tarjan缩点,因为边双连通分量肯定无法移除一条边使得分为不连通的两部分(因为是无向图),然后重新建图,附好点权,就可以开始愉快地跑dfs了,然后不断比较取min即可。但是wa了将近五发之后(检查完了笔误细节),笔者不服了,这个方法肯定是没有问题的,那么问题在哪?笔者发现,这题编号竟然是从0~n-1,我真的说不出话,审题不仔细,简直写到难过,以为改了能对之后,又wa了一发,笔者静下来检查,确保无误后,又提交了一次,又wa了,于是笔者去hdu该题的discuss找到了一组样例,不得不说,wa得心服口服,因为题目输入可能有重边,即0 1 , 1 0,因为是无向图所以存边肯定调用了两次_add(u,v),所以等于0 1之间,有了四条边,如果if (v==pre) then continue,那么就会出错,这个点可以说是很坑人了,只能说是自己疏忽了,但是这个也很好解决,只要多加个flag判断就好。其实也就是两个点的边双连通要考虑。(个人觉得两个点不可能叫边双连通,暂且这样称作吧,即上文0 1 , 1 0


#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <vector>
#define mem(a,b) memset((a),(b),sizeof(a))
using namespace std;const int N = 1e4 + 16;struct Edge
{int u, v, nxt;
};
Edge edge[N<<1], edge2[N<<1];bool vis[N];
int head[N], ecnt;
int head2[N], ecnt2;
int sta[N], dfn[N], low[N], col[N];
int val[N], vv[N], f[N];
int top, dep, sum;
int n, m;void _add( int u, int v )
{edge[ecnt].u = u;edge[ecnt].v = v;edge[ecnt].nxt = head[u];head[u] = ecnt ++;
}void _add2( int u, int v )
{edge2[ecnt2].u = u;edge2[ecnt2].v = v;edge2[ecnt2].nxt = head2[u];head2[u] = ecnt2 ++;
}void init()
{mem(head,-1);mem(vis,0);mem(sta,0);mem(dfn,0);mem(low,0);mem(val,0);top = sum = dep = ecnt = 0;
}void tarjan( int u, int pr )
{sta[++top] = u;low[u] = dfn[u] = ++dep;vis[u] = 1;int flag = 1;for ( int i = head[u]; i+1; i = edge[i].nxt ){int v = edge[i].v;if ( v == pr && flag ){flag = 0;continue;}if ( !dfn[v] ){tarjan( v, u );low[u] = min( low[u], low[v] );}else if ( vis[v] )low[u] = min( low[u], low[v] );}if ( low[u] == dfn[u] ){col[u] = ++sum;vis[u] = 0;while ( sta[top] != u ){col[sta[top]] = sum;vis[sta[top--]] = 0;}top --;}
}void dfs( int u )
{if ( vis[u] ) return ;vis[u] = 1;f[u] += vv[u];for ( int i = head2[u]; i+1; i = edge2[i].nxt ){int v = edge2[i].v;if ( !vis[v] ){dfs(v);f[u] += f[v];}}
}int main()
{while ( ~scanf("%d%d", &n, &m) ){init();int pow = 0;for ( int i = 0; i < n; i ++ ){scanf("%d", &val[i]);pow += val[i];}for ( int i = 0; i < m; i ++ ){int u, v;scanf("%d%d", &u, &v);_add(u,v);_add(v,u);}for ( int i = 0; i < n; i ++ )if ( !dfn[i] )tarjan(i, -1);if ( sum == 1 ){puts("impossible");continue;}mem(head2,-1);ecnt2 = 0;mem(vv,0);mem(f,0);for ( int i = 0; i < n; i ++ ){vv[col[i]] += val[i];for ( int j = head[i]; j+1; j = edge[j].nxt ){int v = edge[j].v;if ( col[i] != col[v] )_add2(col[i],col[v]);}}mem(vis,0);dfs(1);int ans = pow;for ( int i = 1; i <= sum; i ++ )ans = min( ans, abs( pow - f[i] - f[i] ) );//      cout << "sum: " << sum << endl;printf("%d\n", ans);}return 0;
}

转载于:https://www.cnblogs.com/FormerAutumn/p/9615452.html

Graph_Master(连通分量_D_Trajan缩点+dfs)相关推荐

  1. Div1 小A抓小B tarjan双连通分量缩点+dfs

    题目描述 小A和小B在一个无向图G上进行一个游戏.图G是连通的,有n个点,n条边,无重边,无自环,结点编号为1~n.游戏开始前小A在结点x,小B在结点y(x≠y).游戏开始后,小A和小B轮流进行移动( ...

  2. tarjan算法与无向图的连通性(割点,桥,双连通分量,缩点)

    基本概念 给定无向连通图G = (V, E) 割点: 对于x∈V,从图中删去节点x以及所有与x关联的边之后,G分裂为两个或两个以上不相连的子图,则称x为割点 割边(桥) 若对于e∈E,从图中删去边e之 ...

  3. 图论复习之强连通分量以及缩点—Tarjan算法

    图论复习之强连通分量以及缩点-Tarjan算法                                 by RtPYH ----------------------------------- ...

  4. POJ 3352 无向图边双连通分量,缩点,无重边

    为什么写这道题还是因为昨天多校的第二题,是道图论,HDU 4612.当时拿到题目的时候就知道是道模版题,但是苦于图论太弱.模版都太水,居然找不到.虽然比赛的时候最后水过了,但是那个模版看的还是一知半解 ...

  5. 解题报告:luogu P3916 图的遍历( 缩点 + DFS ? × 思维 + 反向建边 + DFS √ )

    题目链接:图的遍历 本题是一个有向图,要求每个点能到达的编号最大的点.由于是有向图,如果直接DFS如果有环就可能忽略一些点,所以我们可以直接缩点 缩点之后 在同一个强联通分量中的点可以相互到达,那么我 ...

  6. Graph_Master(连通分量_Poj_1904)

    Poj_1904 背景:本来是在做Voj的连通分量,做到了E( hdu_4685 ),想到了二分图,但是笔者只会最大匹配,但题目要求要输出所有的最大匹配情况,想了好久都没想出来怎么做,因为如果我已知一 ...

  7. Wikioi 2822爱在心中(强连通缩点+dfs)

    2822 爱在心中(强连通缩点+遍历) 2822 爱在心中 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description " ...

  8. 婴儿名字[连通分量之邻接矩阵与DFS]

    邻接矩阵与DFS 前言 一.婴儿名字 二.邻接矩阵与DFS 总结 参考文献 前言 图的基本功之一,给定节点和边(节点对),统计连通分量的个数,当然也可以以其他形式给出,例如婴儿名字.通过其可练习常见图 ...

  9. [USACO08DEC]在农场万圣节Trick or Treat on the Farm【Tarja缩点+dfs】

    题目描述 每年,在威斯康星州,奶牛们都会穿上衣服,收集农夫约翰在N(1<=N<=100,000)个牛棚隔间中留下的糖果,以此来庆祝美国秋天的万圣节. 由于牛棚不太大,FJ通过指定奶牛必须遵 ...

  10. 图论--双连通E-DCC缩点模板

    // tarjan算法求无向图的桥.边双连通分量并缩点 #include<iostream> #include<cstdio> #include<cstring> ...

最新文章

  1. linux/unix inode的一个面试问题及一些概念
  2. 数据中心冷却技术在企业持续发展中的应用
  3. STM32F103单片机系统时钟部分归纳
  4. Python中的线程间通信
  5. java 伪异步 netty,大话netty系列之--伪异步BIO
  6. leetcode695. 岛屿的最大面积(dfs)
  7. 谷歌AI:根据视频生成深度图,效果堪比激光雷达
  8. 走近深度学习,认识MoXing:初识华为云ModelArts的王牌利器 — MoXing
  9. 【招聘内推】阿里高德地图招聘应用算法专家(P7,含推荐算法方向)
  10. java hbase 例子,java操作hbase例子
  11. 用python实现计算器
  12. Navicat Premium 11.2.7 中文破解版安装
  13. Linux源码安装pgadmin4,赵彦昌博客 - linux ubuntu 安装pgadmin4
  14. arcgis点连线_ArcGIS中,一个点集里的点两两连线,比如有4个点,就连6条线
  15. DTcms Core项目发布到IIS教程
  16. 微信 JS-SDK 说明文档
  17. Wireshark捕获过滤器
  18. Livezilla on Linux 安装配置教程
  19. Instability Analysis and Oscillation Suppression of Enhancement-Mode GaN Devices--GaN半桥电路中不稳定分析
  20. 【论文阅读】【HLLDA】 A Hierarchical Model of Web Summaries

热门文章

  1. Multimedia框架
  2. 十大虚拟化最佳实践(转自Wes Miller的文章)
  3. 1093-A+B for Input-Output Practice (V)
  4. 详细分析《三合一收款码》后台程序识别原理
  5. 应用之星:H5制作教程-最好用的H5制作工具
  6. html中首行缩进怎么写,HTML怎么实现首行缩进两个字符?
  7. 车内看车头正不正技巧_侧方位停车把把入库技巧,驾校没教的中途修正方法很实用...
  8. 简约商务风ppt模板推荐
  9. 联想笔记本更换硬盘/改Win 7系统安装过程中报0x000000A5蓝屏
  10. Linux——RAID磁盘阵列及配置