题目一眼看去以为是4-sat。。。

题意:给n(n<=3000)个黑方块的坐标,保证黑方块没有公共边。对于每个黑方块选一个角作为结点,使得所选结点满足输入的一个无向图。其中距离为曼哈顿距离。输出是否有解。possible或impossible。

对于每个黑方块,4个角落必须选且仅选一个。一开始2-sat建模是对于一个pnt[i],有4对点pnt[i][0], pnt[i][0]', pnt[i][1], pnt[i][1]', pnt[i][2], pnt[i][2]', pnt[i][3], pnt[i][3]'。但是这样建模只能保证4个角落至多选一个(pnt[i][j]连pnt[i][k]' (k!=j)),保证不了至少选一个。

参考别人代码,发现神做法。类似2-sat的嵌套。。。01染色+2sat

把4个角落分组,左上和右下为第0组,右上和左下为第1组。(因为左上和右下的曼哈顿距离为2,有可能共存;右上和左下同理)。而左上和右上不可能共存,左上和左下同理。(没必要也没有意义把不共存的分为一组。)

通过染色,可以确定每个黑方块只有2种选择(黑方块染为第0组,则只能选左上或右下,且必须选且仅选一个;第1组同理)。到这里就可以看得出,显然的2-sat模型。感觉就像是2*2sat==4sat。

#pragma comment (linker,"/STACK:102400000,102400000")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
#include <queue>
#include <set>
#include <map>
#include <stack>
using namespace std; #define eps 1e-8
#define ll long long
#define mxn 2600
#define mxe 26000
#define inf 0x3f3f3f3f
#define MP make_pair #define maxn 6060
#define maxm 310000*8 struct Edge{
int v,w,nxt;
}e[maxm];
int head[maxn],esz;
void init(){esz=0;memset(head,-1,sizeof(head));}
void addedge(int u,int v,int w){
e[esz].v=v,e[esz].w=w,e[esz].nxt=head[u];
head[u]=esz++;
} struct SAT{
Edge e[maxm];
int head[maxn], em;
void init(){em=0;memset(head,-1,sizeof(head));}
void add(int u,int v){
e[esz].v=v,e[esz].nxt=head[u];
head[u]=esz++;
}
int dfn[maxn],low[maxn],id,cnt;
bool ins[maxn];
int st[maxn],top;
int belong[maxn];
void strong(int x,int fa){
dfn[x]=low[x]=++id;
st[top++]=x;
ins[x]=true;
for(int i=head[x];i!=-1;i=e[i].nxt){
int v = e[i].v;
if(!dfn[v]){
strong(v,x);
low[x] = min(low[x],low[v]);
}else if(ins[v]) low[x] = min(low[x], dfn[v]);
}
if(dfn[x]==low[x]){
int u=-1;++cnt;
while(u!=x){
u = st[--top];
ins[u]=false;
belong[u]=cnt;
}
}
}
bool tarjan(int n){
id=cnt=top=0;
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(ins,0,sizeof(ins));
for(int i=0;i<n;++i) if(!dfn[i]) strong(i,-1);
for(int i=0;i<n;i+=2) if(belong[i]==belong[i^1]) return false;
return true;
}
}sat; int dx[2][2]={{0,1},{0,1}};
int dy[2][2]={{0,1},{1,0}};
struct Pnt{
int x,y;
Pnt(){}
Pnt(int xx,int yy):x(xx),y(yy){}
}pnt[maxn];
Pnt pp[maxn][2];
int dis(Pnt a,Pnt b){return abs(a.x-b.x)+abs(a.y-b.y);}
int kind[maxn];
bool color(int u,int sign){
kind[u] = sign;
for(int i=head[u];i!=-1;i=e[i].nxt){
int v = e[i].v;
int sign2 = (dis(pnt[u],pnt[v])&1)^(e[i].w&1)^sign;
if(kind[v]==-1){
if(color(v,sign2)==false) return false;
}else if(kind[v]!=sign2) return false;
}
return true;
}
bool jud(int u,int sign,int n){
memset(kind,-1,sizeof(kind));
if(color(u,sign)==false) return false;
for(int i=1;i<=n;++i){
pp[i][0] = Pnt(pnt[i].x+dx[kind[i]][0], pnt[i].y+dy[kind[i]][0]);
pp[i][1] = Pnt(pnt[i].x+dx[kind[i]][1], pnt[i].y+dy[kind[i]][1]);
}
sat.init();
for(int i=1;i<=n;++i){
if(kind[i]==-1) continue;
for(int j=head[i];j!=-1;j=e[j].nxt){
int to = e[j].v;
int w = e[j].w;
int dis1 = dis(pp[i][0], pp[to][0]);
int dis2 = dis(pp[i][0], pp[to][1]);
if(dis1!=w || dis2!=w){
if(dis1!=w && dis2!=w){
sat.add(2*i-2,2*i-1);
}else if(dis1==w){
sat.add(2*i-2,2*to-2);
}else if(dis2==w){
sat.add(2*i-2,2*to-1);
}
} dis1 = dis(pp[i][1], pp[to][0]);
dis2 = dis(pp[i][1], pp[to][1]);
if(dis1!=w || dis2!=w){
if(dis1!=w && dis2!=w){
sat.add(2*i-1,2*i-2);
}else if(dis1==w){
sat.add(2*i-1,2*to-2);
}else if(dis2==w){
sat.add(2*i-1,2*to-1);
}
}
}
}
bool ans = sat.tarjan(n*2);
return ans;
}
int fa[maxn];
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
int main(){
int t,n,m;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%d%d",&pnt[i].x,&pnt[i].y);
scanf("%d",&m);
init();
for(int i=0;i<=n;++i) fa[i]=i;
for(int i=0;i<m;++i){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
addedge(v,u,w);
fa[find(u)] = find(v);
}
bool yes = true;
for(int i=1;i<=n;++i){
if(i==fa[i]){
if(jud(i,0,n)==false && jud(i,1,n)==false){
yes = false;
break;
}
}
}
if(yes) puts("possible");
else puts("impossible");
}
return 0;
}

UVALive 4849 String Phone(2-sat、01染色)的更多相关文章

  1. org.codehaus.jackson.map.JsonMappingException: Can not construct instance of java.util.Date from String value '2012-12-12 12:01:01': not a valid representation (error: Can not parse date "2012-12-

    Jackson对于date的反序列化只支持几种,如果不符合默认格式则会报一下错误 org.codehaus.jackson.map.JsonMappingException: Can not cons ...

  2. 训练指南 UVALive - 3523 (双联通分量 + 二分图染色)

    layout: post title: 训练指南 UVALive - 3523 (双联通分量 + 二分图染色) author: "luowentaoaa" catalog: tru ...

  3. Solr部分更新MultiValued的Date日期字段时报错及解决方案:Invalid Date String:'Mon Sep 14 01:48:38 CST 2015'

    问题描述如标题. 异常信息如下: Result Caused by: org.apache.solr.common.SolrException: Invalid Date String:'Mon Se ...

  4. UVALive 4423 String LD 暴力

    A - String LD Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Stat ...

  5. 【01染色法判断二分匹配+匈牙利算法求最大匹配】HDU The Accomodation of Students

    http://acm.hdu.edu.cn/showproblem.php?pid=2444 [DFS染色] #include<iostream> #include<cstdio&g ...

  6. UVALive 6663 Count the Regions 离散+bfs染色_(:зゝ∠)_

    题目链接:option=com_onlinejudge&Itemid=8&page=show_problem&problem=4675">点击打开链接 gg.. ...

  7. UVALive 4394 String painter ——(区间DP)

    其实这个dp过程有点似懂非懂...代码如下: #include <stdio.h> #include <algorithm> #include <string.h> ...

  8. UVALive 6663 Count the Regions --离散化+DFS染色

    题意:给你n(n<=50)个矩形(左上角坐标和右下角坐标),问这些矩形总共将平面分成多少个部分.坐标值可能有1e9. 分析:看到n和坐标的范围,容易想到离散化,当时就没想到离散化以后怎么判断区域 ...

  9. UVALive 4394 String painter

    这题搞了很久很久..弄得我都不想放上来了,但是想了想还是写上来吧,万一以后忘了怎么做了,又得搞很久很久了.题目是要求把一个字符串变成另外一个,每次可以选择一段字符串变成同一个字符,问最少用变多少次.本 ...

随机推荐

  1. knockoutJS学习笔记04:监控属性

    一.语法介绍 先来看一个简单的例子: <span data-bind="text:name"></span> var obj = {name:ko.obse ...

  2. Caliburn.Micro学习笔记(二)----Actions

    Caliburn.Micro学习笔记目录 上一篇已经简单说了一下引导类和简单的控件绑定 我的上一个例子里的button自动匹配到ViewModel事件你一定感觉很好玩吧 今天说一下它的Actions, ...

  3. 吉特仓库管理系统-.NET打印问题总结

    在仓储系统的是使用过程中避免不了的是打印单据,仓库系统中包含很多单据:入库单,出库单,盘点单,调拨单,签收单等等,而且还附带着很多的条码标签的打印.本文在此记录一下一个简单的打印问题处理方式.处理问题 ...

  4. 反射在ADO.NET中的运用(你还在每个项目中循环遍历DataTable吗)

    图片有点大哈,但大更能说明问题.您是不是每个项目都在重复的做图片中的事情-----循环把数据库中返回的表转化为实体对象.是不是每次都在抱怨这样的重复工作.字段越多抱怨越多!不用抱怨了.当你看到这篇文章 ...

  5. .NET添加时间戳防止重放攻击

    如过客户端在向服务端接口进行请求,如果请求信息进行了加密处理,被第三方截取到请求包,虽然第三方无法解密获取其中的数据,但是可以使用该请求包进行重复的请求操作.如果服务端不进行防重放攻击,就会参数服务器 ...

  6. apt-get 相關設定

    /etc/apt/apt.conf.d/01proxy 若加了以下這行,則 apt-get 都會透過下方網址get Acquire::http::Proxy "http://aptcache ...

  7. haproxy实现自定义错误页面的内容

    现在利用haproxy实现自定义的haproxy的错误页面 我们现在实现自定义错误页面有以下的方法: 一种是自定义错误页面 haproxy.conf defaults errorfile 404 /e ...

  8. getline数据来源你的三种方式

    (1)getline从交互式的用户输入中\c中获取内容: # awk 'BEGIN {system("echo \"Input your name:\"");g ...

  9. UEditor独立图片、文件上传模块

    百度的UEditor编辑器的强大之处不用多说,但是有时候我们只想用他的文件.图片上传模块,不想把这个编辑器加载出来,话不多说,直接上实现代码: 引用文件: <script src="~ ...

  10. Mvc视图引擎、寻址规则

    目前MVC中用的较多的视图引擎应该是WebFormViewEngine和RazorViewEngine了. 一个Request请求首先会进入Routing进行判断,对于错误的url是不能被路由匹配到的 ...