开篇

这是我写的第一篇记录好题的博客,也是博客园上我发布的第一篇博客。

以后我的所有博客都将在洛谷和博客园上同时发布,同志们有兴趣的在哪里都可以看一看。

[https://www.luogu.com.cn/blog/DarthVictor/#](洛谷博客)
[https://www.cnblogs.com/DarthVictor/](博客园)

那么今天要记录的就是:空调教室!

题目

题面

众所周知,HDU的考研教室是没有空调的,于是就苦了不少不去图书馆的考研仔们。Lele也是其中一个。而某教室旁边又摆着两个未装上的空调,更是引起人们无限YY。

一个炎热的下午,Lele照例在教室睡觉的时候,竟然做起了空调教室的美梦。

Lele梦到学校某天终于大发慈悲给某个教室安上了一个空调。而且建造了了M条通气管道,让整个教学楼的全部教室都直接或间接和空调教室连通上,构成了教室群,于是,全部教室都能吹到空调了。

不仅仅这样,学校发现教室人数越来越多,单单一个空调已经不能满足大家的需求。于是,学校决定封闭掉一条通气管道,把全部教室分成两个连通的教室群,再在那个没有空调的教室群里添置一个空调。

当然,为了让效果更好,学校想让这两个教室群里的学生人数尽量平衡。于是学校找到了你,问你封闭哪条通气管道,使得两个教室群的人数尽量平衡,并且输出人数差值的绝对值。

Input
    
本题目包含多组数据,请处理到文件结束。

每组测试第一行包含两个整数N和M(0<N<=10000,0<M<20000)。其中N表示教室的数目(教室编号从0到N-1),M表示通气管道的数目。

第二行有N个整数Vi(0<=Vi<=1000),分别代表每个教室的人数。
    
接下来有M行,每行两个整数Ai,Bi(0<=Ai,Bi<N),表示教室Ai和教室Bi之间建了一个通气管道。

Output

对于每组数据,请在一行里面输出所求的差值。

如果不管封闭哪条管道都不能把教室分成两个教室群,就输出"impossible"。

Sample Input

4 3

1 1 1 1

0 1

1 2

2 3

4 3
    
1 2 3 5
    
0 1
    
1 2
    
2 3

Sample Output

0
    
1

解说

这道题用的方法应该是Tarjan边双+缩点,网上大部分的讲解都说要用树形DP,但是还没学到,只能自己再想方法。

最开始的时候想简单了,觉得求出每个边双连通分量的人数,放进数组里,跑一遍背包,求出把这些数分成两组的最小差值,就行了,样例还过了,就是A不了……被老郭一说才发现这是个图啊,直接当一组数分的话一组可能根本连不起来……

只不过是从头再来……

改了改想法,求出边双之后先缩点,变成一棵树,然后……

我没听说过树形DP是个什么东西啊!

万能DFS吧。

随便找一个点作为根节点,DFS过程就是依次往下搜它的儿子,返回值就是它自己的权值加下面子孙的权值,每次加完abs(计算总人数-2 * 自己的人数),然后和ans取最小值。(不知道这个式子怎么来的?差值=(总人数-第一部分人数)-第一部分人数)

完成!Ура!

咦?还不对?

再检查发现犯了两个 极其愚蠢的 错误。边数组开的时候没乘2,ans初始值设成了1000(应为10000000,万一有10001个点,其中10000个一撮,每个点的权值都为1000呢?)

幸甚至哉,歌以咏志。

 #include<bits/stdc++.h>
using namespace std;
const int maxn=+,maxe=*+;
int head[maxn],dfn[maxn],low[maxn],rs[maxn],f[maxn],belong[maxn];
int h[maxn],ans;
bool bridge[maxe],vis[maxn];
int n,m,tot,sum,dfs_clock;bool judge;
struct edge{
int to,next;
}e[maxe],ed[maxe];
void Add(int a,int b){
e[tot].to=b;
e[tot].next=head[a];
head[a]=tot;
tot++;
}
void tarjan(int u,int id){
dfn[u]=low[u]=++dfs_clock;
for(int i=head[u];i;i=e[i].next){
if(i==(id^)) continue;
int v=e[i].to;
if(!dfn[v]){
tarjan(v,i);
low[u]=min(low[u],low[v]);
if(dfn[u]<low[v]){
judge=;
bridge[i]=bridge[i^]=;
}
}
else low[u]=min(low[u],dfn[v]);
}
}
void dfs(int x,int id){
vis[x]=;
f[id]+=rs[x];
belong[x]=id;
for(int i=head[x];i;i=e[i].next){
if(!bridge[i]&&!vis[e[i].to]) dfs(e[i].to,id);
}
}
int dfs2(int x){
vis[x]=;
for(int i=h[x];i;i=ed[i].next){
int to=ed[i].to;
if(!vis[to]) f[x]+=dfs2(to);
}
ans=min(ans,abs(sum-*f[x]));
return f[x];
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
tot=; sum=; judge=; dfs_clock=;
memset(f,,sizeof(f));
memset(e,,sizeof(e));
memset(h,,sizeof(h));
memset(ed,,sizeof(ed));
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(vis,,sizeof(vis));
memset(head,,sizeof(head));
memset(belong,,sizeof(belong));
memset(bridge,,sizeof(bridge));
for(int i=;i<=n;i++){
scanf("%d",&rs[i]);
sum+=rs[i];
}
for(int i=;i<=m;i++){
int a,b;
scanf("%d%d",&a,&b);
Add(a+,b+);
Add(b+,a+);
}
for(int i=;i<=n;i++) if(!dfn[i]) tarjan(i,head[i]);
if(!judge){
printf("impossible\n");
continue;
}
int id=;
for(int i=;i<=n;i++) {
if(!belong[i]){
id++;
dfs(i,id);
}
}
tot=;
for(int i=;i<=n;i++){
for(int j=head[i];j;j=e[j].next){
int from=belong[i],to=belong[e[j].to];
if(from!=to){
ed[tot].to=to;
ed[tot].next=h[from];
h[from]=tot;
tot++;
/*ed[tot].to=from;
ed[tot].next=h[to];
h[to]=tot;
tot++;*/
}
}
}
ans=;
memset(vis,,sizeof(vis));
dfs2();
printf("%d\n",ans);
} }

看看代码吧

开篇词The Start以及[Vjudge][HDU2242]空调教室的更多相关文章

  1. 【Bluetooth蓝牙开发】一、开篇词 | 打造全网最详细的Bluetooth开发教程

    个人主页:董哥聊技术 我是董哥,嵌入式领域新星创作者 创作理念:专注分享高质量嵌入式文章,让大家读有所得! 文章目录 1.前言 2.蓝牙综合介绍 3.精华文章汇总 4.结语 1.前言 大家好,我是董哥 ...

  2. 考研系列 HDU2242之空调教室 tarjan

    众所周知,HDU的考研教室是没有空调的,于是就苦了不少不去图书馆的考研仔们.Lele也是其中一个.而某教室旁边又摆着两个未装上的空调,更是引起人们无限YY. 一个炎热的下午,Lele照例在教室睡觉的时 ...

  3. HDU2242 考研路茫茫——空调教室 (双联通分+树形DP)

    考研路茫茫——空调教室 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  4. HDU 2242 考研路茫茫——空调教室 无向图缩环+树形DP

    考研路茫茫——空调教室 Problem Description 众所周知,HDU的考研教室是没有空调的,于是就苦了不少不去图书馆的考研仔们.Lele也是其中一个.而某教室旁边又摆着两个未装上的空调,更 ...

  5. HDU 2242 考研路茫茫----空调教室

    传送门 考研路茫茫——空调教室 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  6. HDU 2242 考研路茫茫——空调教室

    考研路茫茫——空调教室 http://acm.hdu.edu.cn/showproblem.php?pid=2242 分析: 树形dp,删边. 代码: #include<cstdio> # ...

  7. HDU 2242 考研路茫茫——空调教室(边双连通)

    HDU 2242 考研路茫茫--空调教室 题目链接 思路:求边双连通分量.然后进行缩点,点权为双连通分支的点权之和,缩点完变成一棵树,然后在树上dfs一遍就能得出答案 代码: #include < ...

  8. hdu2242 考研路茫茫——空调教室

    弱联通 #include<iostream> #include<cstdio> #include<cstring> #include<map> #inc ...

  9. 深入剖析Kubernetes学习笔记:开篇词(00)

    一.关于Kubernetes初学的疑惑 就在这场因"容器"而起的技术变革中,kubernetes项目已经成为容器技术的事实标准,重新定义了基础设置领域对应用编排与管理的种种可能 1 ...

随机推荐

  1. 未来科技城 x 奇点云打造「企业数据大脑」,助力1.3万家企业服务

    “当前,政府数字化和数字政府建设已成为一种趋势.一种必然,并且有了一条水到渠成式的实现路径.” 上升为国家战略的数字中国建设加速了”智慧政务“的生动实践,杭州未来科技城的「企业数据大脑」就是一个典型. ...

  2. Python与数据库

    链接汇总 https://www.cnblogs.com/stacklike/category/1134822.html Python与数据库[1] -> 数据库接口/DB-API[0] -&g ...

  3. Anaconda 安装、TensorFlow 安装、pytorch 安装

    问题 1 假设已经安装完Anaconda Navigator,按照 网址:https://www.zhihu.com/question/55577586 的教程操作,设置镜像源地址,安装. 问题 2: ...

  4. 3dmax2015卸载/安装失败/如何彻底卸载清除干净3dmax2015注册表和文件的方法

    3dmax2015提示安装未完成,某些产品无法安装该怎样解决呢?一些朋友在win7或者win10系统下安装3dmax2015失败提示3dmax2015安装未完成,某些产品无法安装,也有时候想重新安装3 ...

  5. [LC] 74. Search a 2D Matrix

    Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the follo ...

  6. java 二分法查找原理

    二分法查找原理: 1.只要低位下标不大于高位下标,就进行二分查找(步骤1-3) 2.先在有序的数组中对半查找中间的坐标,如果中标和要查找的下标相等时,找到目标数,那二分结束. 3.如果步骤2没有找到, ...

  7. Archives: 2013/6

    OpenStack环境搭建 这一步有两个选择: 一种就是正统的真实搭建,所有都按生产环境来部署,费时费力. 还有一种就是官方推荐的一键安装DevStack,直接安装最新的版本,体验最新的特性. 至于如 ...

  8. 最长递增子序列-dp问题

    Longest Increasing Subsequence The longest increasing subsequence problem is to find a subsequence o ...

  9. annoy超平面多维近似向量查找工具

    需求:有800万的中文词向量,要查询其中任意一个词向量对应的k个与其最邻近的向量.通常情况下如果向量集比较小的话,几十万个向量(几个G这种),我们都可以用gensim的word2vec来查找,但是88 ...

  10. Pip安装TensorFlow报错:MemoryError

    问题描述 使用pip安装TensorFlow时,一直报错,情况如下: 解决办法 使用如下命令可正常安装: pip3 install --no-cache-dir tenstoflow --no-cac ...