开篇词The Start以及[Vjudge][HDU2242]空调教室
开篇
这是我写的第一篇记录好题的博客,也是博客园上我发布的第一篇博客。
以后我的所有博客都将在洛谷和博客园上同时发布,同志们有兴趣的在哪里都可以看一看。
[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]空调教室的更多相关文章
- 【Bluetooth蓝牙开发】一、开篇词 | 打造全网最详细的Bluetooth开发教程
个人主页:董哥聊技术 我是董哥,嵌入式领域新星创作者 创作理念:专注分享高质量嵌入式文章,让大家读有所得! 文章目录 1.前言 2.蓝牙综合介绍 3.精华文章汇总 4.结语 1.前言 大家好,我是董哥 ...
- 考研系列 HDU2242之空调教室 tarjan
众所周知,HDU的考研教室是没有空调的,于是就苦了不少不去图书馆的考研仔们.Lele也是其中一个.而某教室旁边又摆着两个未装上的空调,更是引起人们无限YY. 一个炎热的下午,Lele照例在教室睡觉的时 ...
- HDU2242 考研路茫茫——空调教室 (双联通分+树形DP)
考研路茫茫——空调教室 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU 2242 考研路茫茫——空调教室 无向图缩环+树形DP
考研路茫茫——空调教室 Problem Description 众所周知,HDU的考研教室是没有空调的,于是就苦了不少不去图书馆的考研仔们.Lele也是其中一个.而某教室旁边又摆着两个未装上的空调,更 ...
- HDU 2242 考研路茫茫----空调教室
传送门 考研路茫茫——空调教室 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- HDU 2242 考研路茫茫——空调教室
考研路茫茫——空调教室 http://acm.hdu.edu.cn/showproblem.php?pid=2242 分析: 树形dp,删边. 代码: #include<cstdio> # ...
- HDU 2242 考研路茫茫——空调教室(边双连通)
HDU 2242 考研路茫茫--空调教室 题目链接 思路:求边双连通分量.然后进行缩点,点权为双连通分支的点权之和,缩点完变成一棵树,然后在树上dfs一遍就能得出答案 代码: #include < ...
- hdu2242 考研路茫茫——空调教室
弱联通 #include<iostream> #include<cstdio> #include<cstring> #include<map> #inc ...
- 深入剖析Kubernetes学习笔记:开篇词(00)
一.关于Kubernetes初学的疑惑 就在这场因"容器"而起的技术变革中,kubernetes项目已经成为容器技术的事实标准,重新定义了基础设置领域对应用编排与管理的种种可能 1 ...
随机推荐
- 未来科技城 x 奇点云打造「企业数据大脑」,助力1.3万家企业服务
“当前,政府数字化和数字政府建设已成为一种趋势.一种必然,并且有了一条水到渠成式的实现路径.” 上升为国家战略的数字中国建设加速了”智慧政务“的生动实践,杭州未来科技城的「企业数据大脑」就是一个典型. ...
- Python与数据库
链接汇总 https://www.cnblogs.com/stacklike/category/1134822.html Python与数据库[1] -> 数据库接口/DB-API[0] -&g ...
- Anaconda 安装、TensorFlow 安装、pytorch 安装
问题 1 假设已经安装完Anaconda Navigator,按照 网址:https://www.zhihu.com/question/55577586 的教程操作,设置镜像源地址,安装. 问题 2: ...
- 3dmax2015卸载/安装失败/如何彻底卸载清除干净3dmax2015注册表和文件的方法
3dmax2015提示安装未完成,某些产品无法安装该怎样解决呢?一些朋友在win7或者win10系统下安装3dmax2015失败提示3dmax2015安装未完成,某些产品无法安装,也有时候想重新安装3 ...
- [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 ...
- java 二分法查找原理
二分法查找原理: 1.只要低位下标不大于高位下标,就进行二分查找(步骤1-3) 2.先在有序的数组中对半查找中间的坐标,如果中标和要查找的下标相等时,找到目标数,那二分结束. 3.如果步骤2没有找到, ...
- Archives: 2013/6
OpenStack环境搭建 这一步有两个选择: 一种就是正统的真实搭建,所有都按生产环境来部署,费时费力. 还有一种就是官方推荐的一键安装DevStack,直接安装最新的版本,体验最新的特性. 至于如 ...
- 最长递增子序列-dp问题
Longest Increasing Subsequence The longest increasing subsequence problem is to find a subsequence o ...
- annoy超平面多维近似向量查找工具
需求:有800万的中文词向量,要查询其中任意一个词向量对应的k个与其最邻近的向量.通常情况下如果向量集比较小的话,几十万个向量(几个G这种),我们都可以用gensim的word2vec来查找,但是88 ...
- Pip安装TensorFlow报错:MemoryError
问题描述 使用pip安装TensorFlow时,一直报错,情况如下: 解决办法 使用如下命令可正常安装: pip3 install --no-cache-dir tenstoflow --no-cac ...