图论问题(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种选择,然后相邻两个图只有都和对方连接,才判断他们 ...
随机推荐
- github clone加速
1. 在https://asm.ca.com/zh_cn/ping.php 网址中查询 github.global.ssl.fastly.net 及 github.com 的 china地区 avr ...
- snappy 安装
1 下载snappywget https://kojipkgs.fedoraproject.org//vol/fedora_koji_archive00/packages/snappy/1.1.0/1 ...
- CSS的基础学习
CSS学习 --------学习资源 http://www.csszengarden.com/ CSS语法检查http://jigsaw.w3.org/css-validator/ 配置CSS的方法: ...
- 全链路跟踪TraceId
数据库主键:标示唯一一条数据,譬如唯一商品,唯一订单 全局事务ID:实现分布式事务一致性的必备良药 请求ID:requestId,seesionId,标示一个请求或者一次会话的生命周期 身份证ID:代 ...
- 网格弹簧质点系统模拟(Spring-Mass System by Fast Method)附源码(转载)
转载: https://www.cnblogs.com/shushen/p/5311828.html 弹簧质点模型的求解方法包括显式欧拉积分和隐式欧拉积分等方法,其中显式欧拉积分求解快速,但积分步长 ...
- .NET 跨域问题解决
后端处理:var callback=context.Request.QueryString["callback"].ToString(); context.Response.Wri ...
- MVC三层架构搭建
MVC三层架构搭建 项目主要是用三层来搭建项目,三层分为表现层,数据层和业务层.项目用了目前比较流行的IOC架构.目前流行的IoC 框架有AutoFac,Unity,Spring.NET等,项目中选用 ...
- Python - 集合 - 第十一天
Python 集合 集合(set)是一个无序的不重复元素序列. 可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建 ...
- 解决FastCGI 进程超过了配置的活动超时时限的问题
近日,需要满足测试需求,进行大数据并发测试时,报出[HTTP 错误 500.0 - Internal Server Error E:\PHP\php-cgi.exe - FastCGI 进程超过了配置 ...
- Java面向对象——相关基本定义
Java面向对象——相关基本定义 摘要:本文简单介绍了面向对象的编程方式,以及与之有关的一些基本定义. 面向对象 什么是面向对象 面向对象编程是一种对现实世界建立计算机模型的一种编程方法.简称OOP( ...