图论问题(1) : hdu 1198
题目转自hdu 1198,题目传送门
题目大意:
给你11种单位水管摆放位置,若上下或左右有水管连接则视为这两点相连。
最后让你求这些张图中有几个连通块。
解题思路:
本来觉得这道题很简单,不就一个建图在并查集不就完了吗?
(如果连并查集都不会,请点此学习一下)
当然,并没有这么简单(在T了十几次后终于明白)
然后,我们可以发现,每个单位只有4个方向。
很容易想到用二进制进行状态压缩
压缩代码如下:
int change(char ch)
{
switch(ch)
{
case 'A':return ;
case 'B':return ;
case 'C':return ;
case 'D':return ;
case 'E':return ;
case 'F':return ;
case 'G':return ;
case 'H':return ;
case 'I':return ;
case 'J':return ;
case 'K':return ;
}
}
然后写一个并查集模板就应该可以AC了(本人没试过)
可能是因为T太多回了,所以产生了心理阴影
于是,本人不厌其烦地去写时间复杂度更低的算法
在思考了近10min后,我终于有点头绪了
提到二进制,我最先想到的就是位运算
我就想,这道题能不能用位运算优化呢?
实际上是可以的,在思考了15min后我认可了这种想法
接着我用不到10min的时间肝了一段用位运算优化建图过程的代码
优化核心代码如下:
if(i>&&((e[i][j]>>)&(e[i-][j]>>)&)) Union(i*m+j,(i-)*m+j);
if(j>&&((e[i][j-]>>)&e[i][j]&)) Union(i*m+j,i*m+j-);
p.s.:中间的Union是并查集中的合并
位运算我就不解释了(暴怒蒟蒻在线虐人)
然后,又随便写了10min的并查集模板,就愉快地AC了
AC代码如下:
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
char e[][];
int fa[];
bool vis[];
int ans,n,m;
int Init()
{
for(int i=(n+)*(m+);i>=;i--) fa[i]=i;
}
int change(char ch)
{
switch(ch)
{
case 'A':return ;
case 'B':return ;
case 'C':return ;
case 'D':return ;
case 'E':return ;
case 'F':return ;
case 'G':return ;
case 'H':return ;
case 'I':return ;
case 'J':return ;
case 'K':return ;
}
}
int find(int x)
{
if(fa[x]==x) return x;
else
{
fa[x]=find(fa[x]);
return fa[x];
}
}
void Union(int x,int y)
{
int tmp_x=find(x),tmp_y=find(y);
fa[tmp_y]=tmp_x;
return;
}
int main()
{
while(~scanf("%d%d",&n,&m)&&n!=-)
{
getchar();
Init();
for(int i=;i<n;i++)
{
for(int j=;j<m;j++)
{
scanf("%c",&e[i][j]);
e[i][j]=change(e[i][j]);
if(i>&&((e[i][j]>>)&(e[i-][j]>>)&)) Union(i*m+j,(i-)*m+j);
if(j>&&((e[i][j-]>>)&e[i][j]&)) Union(i*m+j,i*m+j-);
}
getchar();
}
ans=;
memset(vis,,sizeof(vis));
for(int i=;i<n;i++) for(int j=;j<m;j++) if(!vis[find(i*m+j)])
{
vis[find(i*m+j)]=true;
ans++;
}
cout<<ans<<endl;
}
return ;
}
emmmm......
提交之后我发现才14ms......(早知道我就不写位运算优化了)
这道题告诉我们,T了不可怕
可怕的是你害怕T掉,所以就花了更多时间去肝最优解(结果发现没啥卵用!)
图论问题(1) : hdu 1198的更多相关文章
- 图论问题(2) : hdu 1102
题目转自hdu 1102,题目传送门 题目大意: 输入一个n*n的邻接矩阵,其中i行j列代表从i到j的路径的长度 然后又m条路已经帮你修好了,求最短要修多长的路才能使所有村庄连接 不难看出,这道题就是 ...
- hdu 1198 (并查集 or dfs) Farm Irrigation
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1198 有题目图11种土地块,块中的绿色线条为土地块中修好的水渠,现在一片土地由上述的各种土地块组成,需要浇 ...
- HDU 1198
http://acm.hdu.edu.cn/showproblem.php?pid=1198 裸并查集,主要工作在根据题目给出关系构图 #include <iostream> #inclu ...
- hdu 1198 Farm Irrigation(深搜dfs || 并查集)
转载请注明出处:viewmode=contents">http://blog.csdn.net/u012860063?viewmode=contents 题目链接:http://acm ...
- HDU 1198 Farm Irrigation(状态压缩+DFS)
题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=1198 题目: Farm Irrigation Time Limit: 2000/1000 MS (Ja ...
- HDU 1198 Farm Irrigation (并查集优化,构图)
本题和HDU畅通project类似.仅仅只是畅通project给出了数的连通关系, 而此题须要自己推断连通关系,即两个水管能否够连接到一起,也是本题的难点所在. 记录状态.不断combine(),注意 ...
- hdu.1198.Farm Irrigation(dfs +放大建图)
Farm Irrigation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- HDU 1198(并查集)
题意:给你11个图,每一个都有管道,然后给一张由这11个正方形中的n个组成的图,判断有几条连通的管道: 思路:在大一暑假的时候做过这道题,当时是当暴力来做的,正解是并查集,需要进行一下转换: 转换1: ...
- hdu 1198 Farm Irrigation
令人蛋疼的并查集…… 我居然做了大量的枚举,居然过了,我越来越佩服自己了 这个题有些像一个叫做“水管工”的游戏.给你一个m*n的图,每个单位可以有11种选择,然后相邻两个图只有都和对方连接,才判断他们 ...
随机推荐
- 解决 cannot find reference 'LSHForest' in '__init__.py'
from sklearn.neighbors import LSHForest cannot find reference 'LSHForest' in '__init__.py'报错 pip3 li ...
- HTML+css基础 css选择器的种类
css选择器的种类 标签 权重是001 类 class权重是0010 相当于255个标签选择器 Id 权重是0100相当于255个类 *通配符 代表所有的标签 权重是0000 后代选 ...
- 转:对softmax讲解比较清楚的博客
https://blog.csdn.net/wgj99991111/article/details/83586508
- mysql批量更新数据(性能优化) 第一种方式
首先想到的是,一条一条更新的速度太慢了,然后就想批量更新,一次更新N条数据.实践是检验真理的唯一标准,不一会儿,代码就敲完了,重新试了一下,效果依旧不理想.啊哦,真是要崩溃!后面又想到了利用异步,我一 ...
- 对try catch finally的理解
对try catch finally的理解1.finally 总是会运行的,即使在catch中thorw抛出异常了. 2.finally 在 return后没有结束,而是继续运行finally 2. ...
- C# 练习题 打印出100-999之间所有的”水仙花数”
题目:打印出100-999之间所有的”水仙花数”,所谓”水仙花数”是指一个三位数,其各位数字立方和等于该数本身.例如:153是一个”水仙花数”,因为153=1的三次方+5的三次方+3的三次方.1.程序 ...
- select和checkbox回绑
$("#STATUS option[value=" + STATUS + "]").attr("selected", true);[sele ...
- synchronized和volatile使用
synchronized和volatile volatile :保证内存可见性,但是不保证原子性: synchronized:同步锁,既能保证内存可见性,又能保证原子性: synchronized实现 ...
- Java基础—内部类
在Java语言中,可以把一个类定义到另一个类的内部,在类里面的这个类就叫作内部类,外面的类叫作外部类.在这种情况下,这个内部类可以被看成外部类的是一个成员(与类的属性和方法类似).还有一种类被称为顶层 ...
- Linux CentOS 下安装.net core sdk
注册Microsoft密钥 sudo rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm ...