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;
}

Graph_Master(连通分量_D_Trajan缩点+dfs)的更多相关文章

  1. Graph_Master(连通分量_C_Trajan缩点+最小路径覆盖)

    hdu_3861 题目大意:给定一张有向图,若<u,v>可达(u可以走到v,或者 v可以走到u),则<u,v>需被划分在统一城邦,问最小划分城邦数. 题解:比较裸的题,可以看出 ...

  2. Graph_Master(连通分量_G_Trajan+Thought)

    Graph_Master~(连通分量) 题目大意:给出m条边(隧道,无向),每条边连接两个点(矿场).要在这些矿场中建设救援出口,防止矿场坍塌造成人员伤亡,问最少需要几个救援出口,以及对应方案数.(假 ...

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

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

  4. tarjan算法求无向图的桥、边双连通分量并缩点

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

  5. PAT Advanced 1013 Battle Over Cities (25) [图的遍历,统计连通分量的个数,DFS,BFS,并查集]

    题目 It is vitally important to have all the cities connected by highways in a war. If a city is occup ...

  6. [HDOJ4612]Warm up(双连通分量,缩点,树直径)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4612 所有图论题都要往树上考虑 题意:给一张图,仅允许添加一条边,问能干掉的最多条桥有多少. 必须解决 ...

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

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

  8. Codeforces 1027D Mouse Hunt (强连通缩点 || DFS+并查集)

    <题目链接> 题目大意: 有n个房间,每个房间都会有一只老鼠.处于第i个房间的老鼠可以逃窜到第ai个房间中.现在要清理掉所有的老鼠,而在第i个房间中防止老鼠夹的花费是ci,问你消灭掉所有老 ...

  9. HDU 3639 Hawk-and-Chicken (强连通缩点+DFS)

    <题目链接> 题目大意: 有一群孩子正在玩老鹰抓小鸡,由于想当老鹰的人不少,孩子们通过投票的方式产生,但是投票有这么一条规则:投票具有传递性,A支持B,B支持C,那么C获得2票(A.B共两 ...

随机推荐

  1. TCP requires two packet transfers to set up the connection before it can send data

    wHTTP重用现存连接来减少TCP建立时延. HTTP The Definitive Guide 4.2.3 TCP Connection Handshake Delays When you set ...

  2. postfix邮箱服务器修改附件大小限制遇到的问题与解决

    Q1:邮件大小限制为30M,发送的附件大小为25M,发送后提示邮件大小超过限制 A:邮箱客户端在发送邮件时会把附件进行base64转码,转码之后邮件大小会超过附件+正文的大小,所以10M的附件在经过转 ...

  3. 通过Nginx反向代理实现IP分流

    通过Nginx做反向代理来实现分流,以减轻服务器的负载和压力是比较常见的一种服务器部署架构.本文将分享一个如何根据来路IP来进行分流的方法. 根据特定IP来实现分流 将IP地址的最后一段最后一位为0或 ...

  4. 【tensorflow】

    运行计算图 session.run() https://blog.csdn.net/sinat_39372048/article/details/80868168 赋值 tf.assign() tf. ...

  5. Drainage Ditches---hdu1532(最大流, 模板)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1532 最大流模板题: EK:(复杂度为n*m*m); #include<stdio.h> ...

  6. 12.Project Fields to Return from Query-官方文档摘录

    1 插入例句 db.inventory.insertMany( [ { item: "journal", status: "A", size: { h: 14, ...

  7. ruamel.yaml 将字典写入yaml文件

    #安装 pip install ruamel.yaml import os from ruamel import yaml # 将字典写入到yaml my_dic = { 'name': '张三', ...

  8. git获取远程仓库代码

    首先在本地创建一个目录“ MyProject”,用来存放工程文件,git进入该文件夹,执行 git clone 远程项目MyCode地址 将代码克隆到本地然后进入“MyCode”文件夹下 cd MyC ...

  9. 20165324 《Java程序设计》第九周学习总结

    学号 20165324 <Java程序设计>第九周学习总结 教材学习内容总结 第十三章 Java网络编程 URL类 使用URL创建对象的应用程序称为客户端 一个URL对象封装一个具体资源的 ...

  10. CCTV-2《遇见大咖》专访雷军----笔记记录

    与央视记者约好两点采访,但因为公司会议拖到了三点.雷军对此表示抱歉,解释了一天的行程,并说:“今天不算密的,密的平均一天应该有十一个会.然后我现在基本每天中午饭,大概就是三分钟的时间.” 因为要上镜, ...