题意:有一个未知的边权为$1$的图,给定所有点到$1$的最短路$a_i$和到$2$的最短路$b_i$,问是否存在这样的图,如果存在,问图中最少有多少条边

先考虑$a_i$,有$a_1=0,a_i\neq0(i\neq1)$,对于一条边$(x,y)$有$|a_x-a_y|\leq1$,对于任意$x\neq1$,存在$(x,y)$使得$a_x-1=a_y$,对$b_i$也有类似的约束

所以,我们将点$i$作为$(a_i,b_i)$画在平面上,那么至少要有两条边:第一条连到$(a_i-1,b_i-1)$或$(a_i-1,b_i)$或$(a_i-1,b_i+1)$,第二条连到$(a_i-1,b_i-1)$或$(a_i,b_i-1)$或$(a_i+1,b_i-1)$,如果这时找不到可以连边的点,那么就无解了(点$1$不用连第一种边,点$2$不用连第二种边)

如果可以连,那么我们构造出了一个有$2n-2$条边的图,显然这个图是满足条件的

但我们要最小化图中边数,所以考虑寻找尽可能多的可以共用的边

以下我们将第一种边称为$a$边,第二种边称为$b$边,共用边只可能是两种情况:1.对于点$i$,存在$(a_i-1,b_i-1)$,此时$i$的$a$边和$b$边可以共用;2.存在$i,j$使得$a_i-1=a_j,b_i+1=b_j$,此时$i$的$a$边可以和$j$的$b$边共用

我们把这$2n-2$条边看成点,如果两条边可以共用,在代表它们的点之间连一条边,求最大匹配即可,虽然是一般图,但注意到只有那些满足$a_i+b_i$相等的点$i$引出的边才可能共用,所以建出来的图是这样的(图来自官方题解)

图中框代表某个坐标$(a_i,b_i)$上的点,红点代表$b$边,蓝点代表$a$边,如果方框内有连边说明存在$(a_i-1,b_i-1)$

这种分层图可以从左上往右下贪心选边求最大匹配,实现时只需维护每个坐标的未匹配点个数即可

总时间复杂度为$O(n\log n)$,感觉这题还是不错的

#include<stdio.h>
#include<map>
using namespace std;
map<int,map<int,int> >mp,vis;
int a[100010],b[100010];
bool ex(int x,int y){
	return mp.count(x)&&mp[x].count(y);
}
int main(){
	int n,i,j,s,las,now;
	scanf("%d",&n);
	#define wa {puts("-1");return 0;}
	for(i=1;i<=n;i++){
		scanf("%d%d",a+i,b+i);
		if(i!=1&&a[i]==0)wa
		if(i!=2&&b[i]==0)wa
		mp[a[i]][b[i]]++;
	}
	for(i=1;i<=n;i++){
		if(i!=2){
			if(!(ex(a[i]-1,b[i]-1)||ex(a[i],b[i]-1)||ex(a[i]+1,b[i]-1)))wa
		}
		if(i!=1){
			if(!(ex(a[i]-1,b[i]+1)||ex(a[i]-1,b[i])||ex(a[i]-1,b[i]-1)))wa
		}
	}
	s=0;
	for(i=1;i<=n;i++){
		if(!ex(a[i]-1,b[i]+1)&&!vis[a[i]][b[i]]){
			vis[a[i]][b[i]]=1;
			las=0;
			for(j=0;ex(a[i]+j,b[i]-j);j++){
				now=mp[a[i]+j][b[i]-j];
				s+=min(las,now);
				now-=min(las,now);
				if(ex(a[i]+j-1,b[i]-j-1)){
					s+=now;
					now=min(las,mp[a[i]+j][b[i]-j]);
				}else
					now=mp[a[i]+j][b[i]-j];
				las=now;
			}
		}
	}
	printf("%d",2*n-2-s);
}

[CODE FESTIVAL 2016]Distance Pairs的更多相关文章

  1. 【AtCoder】CODE FESTIVAL 2016 qual A

    CODE FESTIVAL 2016 qual A A - CODEFESTIVAL 2016 -- #include <bits/stdc++.h> #define fi first # ...

  2. 【AtCoder】CODE FESTIVAL 2016 qual B

    CODE FESTIVAL 2016 qual B A - Signboard -- #include <bits/stdc++.h> #define fi first #define s ...

  3. 【AtCoder】CODE FESTIVAL 2016 qual C

    CODE FESTIVAL 2016 qual C A - CF -- #include <bits/stdc++.h> #define fi first #define se secon ...

  4. Atcoder CODE FESTIVAL 2016 Grand Final E - Water Distribution

    Atcoder CODE FESTIVAL 2016 Grand Final E - Water Distribution 题目链接:https://atcoder.jp/contests/cf16- ...

  5. Atcoder CODE FESTIVAL 2016 qual C 的E题 Encyclopedia of Permutations

    题意: 对于一个长度为n的排列P,如果P在所有长度为n的排列中,按照字典序排列后,在第s位,则P的value为s 现在给出一个长度为n的排列P,P有一些位置确定了,另外一些位置为0,表示不确定. 现在 ...

  6. CODE FESTIVAL 2016 qualA Grid and Integers

    划年代久远的水 题意 有一个R*C的棋盘,要求在每个格子上填一个非负数,使得对任意一个2*2的正方形区域,左上角和右下角的数字之和等于左下角和右上角的数字之和.有一些格子已经被填上了数字,问现在能否满 ...

  7. [CODE FESTIVAL 2016]Problem on Tree

    题意:给一棵树,对于一个满足以下要求的序列$v_{1\cdots m}$,求最大的$m$ 对$\forall1\leq i\lt m$,路径$(v_i,v_{i+1})$不包含$v$中除了$v_i,v ...

  8. [CODE FESTIVAL 2016]Encyclopedia of Permutations

    题意:给定一个排列,其中有可能有一些未确定的数,求出所有可能的排列的排名之和 首先我们要知道怎么算一个给定排列的排名,设它为$p_{1\cdots n}$ 排名即为比它小的排列数$+1$,对于每一个比 ...

  9. CODE FESTIVAL 2016 Grand Final 题解

    传送门 越学觉得自己越蠢--这场除了\(A\)之外一道都不会-- \(A\) 贪心从左往右扫,能匹配就匹配就好了 //quming #include<bits/stdc++.h> #def ...

随机推荐

  1. 崩坏3mmd中的渲染技术研究

    http://youxiputao.com/articles/11839 主要是参考该篇文章做一个微小的复盘. 漫反射与高光 文章中的漫反射与高光并不是类似于普通的 resultCol = Diffu ...

  2. Billboard HDU 2795 (线段树)

    题目链接 Problem Description At the entrance to the university, there is a huge rectangular billboard of ...

  3. springmvc4处理get和post请求中文乱码问题

    1.在springmvc4处理get和post请求的问题 参看大牛博客连接:https://blog.csdn.net/qq_41665356/article/details/80234392

  4. js获取链接参数

    var url = location.search; var Request = new Object(); if(url.indexOf("?")!=-1){ var str = ...

  5. LCD 每隔10分钟 自动熄灭 --打开Framebuffer console的时候【转】

    转自:http://blog.csdn.net/liujia2100/article/details/9009063 版权声明:本文为博主原创文章,未经博主允许不得转载. 之前移植LCD的时候,一切正 ...

  6. STM32-内存管理

    转载:http://www.cnblogs.com/guozhikai/p/6031904.html #ifndef __MALLOC_H #define __MALLOC_H #include &q ...

  7. xxx_initcall相关知识

    参考文件include/linux/init.h /* * Early initcalls run before initializing SMP. * * Only for built-in cod ...

  8. SVN--版本控制系统

    引言 SVN是Subversion的简称,是一个开放源代码的版本控制系统,相较于RCS.CVS,它采用了分支管理系统,它的设计目标就是取代CVS.互联网上很多版本控制服务已从CVS迁移到Subvers ...

  9. Network——物理层-练习题与解答

    1. 无线电天线通常在其直径等于无线电波的波长的情况下工作效果最好.合理的天线直径的范围是从1厘米到5米.问所覆盖的频率范围是怎样的? 解答: λf = c , c=3x108 (m/s) 对于λ=1 ...

  10. Django 定制验证码

    一.图片验证码 方式一: def get_validCode_img(request): path=os.path.join(settings.BASE_DIR,'static','image','1 ...