Portal -->agc017

Description

  给你\(n\)块积木,每块积木由三个矩形组成,中间的矩形最高高度为\(h\),左边的矩形高度为\(a_i\)离底边高度为\(c_i\),右边的矩形高度为\(b_i\)离底边高度为\(d_i\),现在要求将这些积木全部拼起来,并且中间部分的底边贴底,每个积木的左边和右边矩形的底边必须完全贴底或者完全贴在别的积木上,积木无法旋转或翻转,问是否存在合法的摆放方案

  

Solution

​  感觉。。emmm不是很好想反正我是想不到了

​  一开始有一个比较直接的想法,如果说积木\(i\)的\(c_i\)为\(0\),那么这个积木可以接在\(d_j=a_i\)的积木\(j\)的右边,类似的如果说积木\(i\)的\(d_i\)为\(0\),那么这个积木可以接在\(c_j=b_i\)的积木\(j\)的左边,然后我们可以考虑将这些积木连起来之类的就可以转化成一个图论问题

​  但实际上。。这并不是最好的转化方式

​  注意到\(h<=200\),实际上我们并不需要将积木看成点,我们可以将积木看成边,对于每一个高度建两个点(称为正点(\(P(x)\))和负点(\(N(x)\))),具体什么意思的话就是。。对于一个拼接处,属于右边的那块对应的是正点,属于左边的那块对应的是负点,具体高度的话就是拼接处的高度,这样讲比较不好理解的话。。举个例子:

​  然后这样一来,连边的话就是对于每个积木,左边矩形对应的点向右边矩形对应的点连一条有向边,在上面这幅图来看的话就是\(P(x)\rightarrow N(y)\),那么现在我们的问题就变成了要在这个有向图中找若干条从正点开始在负点结束的路径,使得所有边都被经过一次(因为一条边对应一个积木)

​  这个时候有一个很机智的转化(这个时候应该疯狂orzdcx大神)

  我们新搞一个超级源之类的点,如果说一个图存在一条这样的路径,那么我们从超级源向这条路径的起点连边,从终点再连一条有向边到超级源,那么我们可以得到一条回路,如果说整个图存在满足上述的“所有边都被经过一次”的划分,那么说明整个图(算上超级源)一定弱连通并且存在欧拉回路,具体构造的话就是。。每次从超级源出发走一条这样的路径回来,重复直到所有的边都经过了一次,这个时候将所有连着超级源的边都删掉就是一种合法的划分了

  那么现在要做的就是判断是否存在欧拉回路了

  一个弱连通图如果要存在欧拉回路,必须满足每个点的入度和出度相等,那么我们就首先可以得到两个限制条件:

(1)对于所有的正点,\(in[i]<=out[i]\)(之所以是\(<=\)是因为超级源会向路径起点连一条边,那么路径起点的入度会\(+1\),而我们的回路是放在整个包含超级源的图里面看的,所以是\(<=\))

(2)对于所有的负点,\(out[i]<=in[i]\)(类似地,终点要向超级源连边所以出度会要\(+1\))

  有了这两个条件之后还有一个问题,就是我们并不能保证整个图连通,再具体一点就是我们会漏掉一个弱连通块满足这个弱连通块中的每一个点入度都和出度相等这种情况,这种情况没有办法通过起点终点与超级源连边的方式构造出欧拉回路(因为要求起点和终点一正一负,所以连了边之后起点和终点的出度和入度必定不相等),所以一旦出现这种情况肯定是无解的,否则的话就一定能按照上面说的构造方式构造出一种划分

  

  代码大概长这个样子

#include<iostream>
#include<cstdio>
#include<cstring>
#define P(x) (x)
#define N(x) (x+h)
using namespace std;
const int N=1e5+10;
int f[N*2],outd[N*2],ind[N*2],ok[N*2];
int n,h;
int get_f(int x){return f[x]=f[x]==x?x:get_f(f[x]);}
void link(int x,int y){
get_f(x); get_f(y);
if (f[x]==f[y]) return;
f[f[y]]=f[x];
}
bool solve(){
for (int i=P(1);i<=P(h);++i)
if (ind[i]>outd[i]) return false;
for (int i=N(1);i<=N(h);++i)
if (ind[i]<outd[i]) return false;
for (int i=P(1);i<=N(h);++i)
if (ind[i]!=outd[i]) ok[get_f(i)]=1;
for (int i=P(1);i<=N(h);++i)
if (!ok[get_f(i)]&&(ind[i]||outd[i])) return false;
return true;
} int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
#endif
int a,b,c,d;
int l,r;
scanf("%d%d",&n,&h);
for (int i=P(1);i<=N(h);++i) f[i]=i,ind[i]=outd[i]=0,ok[i]=0;
for (int i=1;i<=n;++i){
scanf("%d%d%d%d",&a,&b,&c,&d);
l=c?N(c):P(a);
r=d?P(d):N(b);
link(l,r);
++outd[l]; ++ind[r];
}
if (solve()) printf("YES\n");
else printf("NO\n");
}

【agc017E】Jigsaw的更多相关文章

  1. 【Java】「深入理解Java虚拟机」学习笔记(1) - Java语言发展趋势

    0.前言 从这篇随笔开始记录Java虚拟机的内容,以前只是对Java的应用,聚焦的是业务,了解的只是语言层面,现在想深入学习一下. 对JVM的学习肯定不是看一遍书就能掌握的,在今后的学习和实践中如果有 ...

  2. github上最全的资源教程-前端涉及的所有知识体系【转】

    github上最全的资源教程-前端涉及的所有知识体系[转自:蓝猫的博客] 综合类 综合类 地址 前端知识体系 http://www.cnblogs.com/sb19871023/p/3894452.h ...

  3. Python高手之路【六】python基础之字符串格式化

    Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...

  4. 【原】谈谈对Objective-C中代理模式的误解

    [原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...

  5. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

  6. 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新

    [原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...

  7. 【调侃】IOC前世今生

    前些天,参与了公司内部小组的一次技术交流,主要是针对<IOC与AOP>,本着学而时习之的态度及积极分享的精神,我就结合一个小故事来初浅地剖析一下我眼中的“IOC前世今生”,以方便初学者能更 ...

  8. Python高手之路【三】python基础之函数

    基本数据类型补充: set 是一个无序且不重复的元素集合 class set(object): """ set() -> new empty set object ...

  9. Python高手之路【一】初识python

    Python简介 1:Python的创始人 Python (英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/), 是一种解释型.面向对象.动态数据类型的高级程序设计语言,由荷兰人Guido ...

随机推荐

  1. OpenLDAP配置TLS加密传输

    原文发表于cu:2016-07-04 参考文档: 基于OpenSSL自建CA与颁发SSL证书:http://seanlook.com/2015/01/18/openssl-self-sign-ca/ ...

  2. Python数据挖掘——数据概述

    Python数据挖掘——数据概述 数据集由数据对象组成: 数据的基本统计描述 中心趋势度量 均值 中位数 众数 中列数 数据集的最大值和最小值的平均 度量数据分布 极差 最大值与最小值的差 四分位数 ...

  3. leetcode个人题解——#40 Combination Sum2

    思路:解法和39题类似,改动了两处: 1.因为题目要求每个元素只能出现一次(不代表每个数只能有一个,因为数据中会有重复的数字),所以代码中21行搜索时下一次循环的位置+1: 2.将临时存放答案的vec ...

  4. OrderSys---Spring 计划(第一天)

    Sprint 计划会议: 目标: 1.了解需求分析书的内容 2.划分OrderSys的功能模块 3.开始制作原型 Sprint 3 Backlog细化: ID Name Est How to demo ...

  5. jQuery之css

    设置css样式/读取css值 css() 1. 得到第一个p标签的颜色 2. 设置所有p标签的文本颜色为red 3. 设置第2个p的字体颜色(#ff0011),背景(blue),宽(300px), 高 ...

  6. 软工网络15团队作业4-DAY6

    每日例会 昨天的工作. 张陈东芳:sql语句查询商品信息 吴敏烽:商品类的规范化编写 周汉麟:界面的排版优化 林振斌:商品类排序的实现 李智:研究商品信息的显示 全体人员:初次统一调试 今天计划的工作 ...

  7. 性能测试工具Loadrunner使用经验小结(原创更新版)

    1. 引言 1.1. 简介 loadrunner是一种预测系统行为和性能的负载测试工具,它可以轻松创建虚拟用户.创建真实的负载.定位性能问题.重复测试保证系统的高性能 globa-100的注册码:AE ...

  8. PHP对象类型转换

    其他数据类型转换为对象类型 其他数据类型转换为对象类型,得到的结果是:内置标准类(stdclass)的一个对象! 语法形式为: $obj1  =  (object) 其他类型数据: 数组转换为对象:数 ...

  9. 第136天:Web前端面试题总结(理论)

    Web前端面试题总结 HTML+CSS理论知识 1.讲讲输入完网址按下回车,到看到网页这个过程中发生了什么 a. 域名解析 b. 发起TCP的3次握手 c. 建立TCP连接后发起http请求 d. 服 ...

  10. HDU4043_FXTZ II

    题目描述的意思就不说了,自己考虑的时候就是在所有的排列中,碰到大于前面最大的出现数字的时候就乘以一个二分之一,然后求和. 打表后就会发现,答案分子为1*3*5*……*(2*n-1):分母为2*4*6* ...