二分+2-Sat

判断是否可行

输出字典序最小的解

输出字典序可行解

其实这些都是小问题,最重要的是建图,请看论文。

特殊的建边方式,如果a b是一对,a必须选,那么就是b->a建边。

HDU 3062 Party

模板题

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define LL long long
struct node
{
int u,v,next;
}edge[*];
int t,scnt,top;
int first[];
int DFN[];
int Low[];
int Belong[];
int in[],stack[];
void CL()
{
t = top = scnt = ;
memset(first,-,sizeof(first));
memset(DFN,,sizeof(DFN));
}
void add(int u,int v)
{
edge[t].u = u;
edge[t].v = v;
edge[t].next = first[u];
first[u] = t ++;
}
void Tarjan(int u)
{
int v,i;
DFN[u] = Low[u] = ++ t;
in[u] = ;
stack[top++] = u;
for(i = first[u];i != -;i = edge[i].next)
{
v = edge[i].v;
if(!DFN[v])
{
Tarjan(v);
if(Low[u] > Low[v])
{
Low[u] = Low[v];
}
}
else if(in[v] && Low[u] > DFN[v])
{
Low[u] = DFN[v];
}
}
if(DFN[u] == Low[u])
{
scnt ++;
do
{
v = stack[--top];
in[v] = ;
Belong[v] = scnt;
}while(u != v);
}
}
int main()
{
int n,m,a1,a2,c1,c2,i,u,v;
while(scanf("%d%d",&n,&m)!=EOF)
{
CL();
for(i = ;i < m;i ++)
{
scanf("%d%d%d%d",&a1,&a2,&c1,&c2);
u = a1*+c1;
v = a2*+c2;
add(u,v^);
add(v,u^);
}
for(i = ;i < *n;i ++)
{
if(!DFN[i])
{
Tarjan(i);
}
}
for(i = ;i < n;i ++)
{
if(Belong[*i] == Belong[*i+])
break;
}
if(i == n)
printf("YES\n");
else
printf("NO\n");
} return ;
}

HDU 1814 Peaceful Commission

论文上的例题,输出字典序。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define LL long long
#define N 8001
int que[*N];
int flag[*N];
int first[*N];
int t,n,num;
struct node
{
int u,v,next;
}edge[];
void CL()
{
t = ;
memset(first,-,sizeof(first));
memset(flag,,sizeof(flag));
}
void add(int u,int v)
{
edge[t].u = u;
edge[t].v = v;
edge[t].next = first[u];
first[u] = t ++;
}
int dfs(int x)
{
int i,v;
if(flag[x] == )
return ;
else if(flag[x] == )
return ;
flag[x] = ;
flag[x^] = ;
que[num++] = x;
for(i = first[x];i != -;i = edge[i].next)
{
v = edge[i].v;
if(!dfs(v)) return ;
}
return ;
}
int judge()
{
int i,j;
for(i = ;i < *n;i ++)
{
if(flag[i]) continue;
num = ;
if(!dfs(i))
{
for(j = ;j < num;j ++)
{
flag[que[j]] = ;
flag[que[j]^] = ;
}
if(!dfs(i^))
return ;
}
}
return ;
}
int main()
{
int m,u,v,i;
while(scanf("%d%d",&n,&m)!=EOF)
{
CL();
for(i = ;i < m;i ++)
{
scanf("%d%d",&u,&v);
u --;
v --;
add(u,v^);
add(v,u^);
}
if(judge())
{
for(i = ;i < *n;i ++)
{
if(flag[i] == ) printf("%d\n",i+);
}
}
else
{
printf("NIE\n");
}
}
return ;
}

HDU 3648 Wedding

输出可行解。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <algorithm>
using namespace std;
#define LL long long
struct node
{
int u,v,next;
}edge[],g[];
int t,scnt,top,T;
int first[];
int DFN[];
int op[];
int Low[];
int Belong[];
int in[],stack[];
int input[];
int flag[];
void CL()
{
T = t = top = scnt = ;
memset(first,-,sizeof(first));
memset(DFN,,sizeof(DFN));
memset(flag,,sizeof(flag));
}
void add(int u,int v)
{
edge[t].u = u;
edge[t].v = v;
edge[t].next = first[u];
first[u] = t ++;
}
void _add(int u,int v)
{
g[T].u = u;
g[T].v = v;
g[T].next = first[u];
first[u] = T ++;
}
void Tarjan(int u)
{
int v,i;
DFN[u] = Low[u] = ++ t;
in[u] = ;
stack[top++] = u;
for(i = first[u];i != -;i = edge[i].next)
{
v = edge[i].v;
if(!DFN[v])
{
Tarjan(v);
if(Low[u] > Low[v])
{
Low[u] = Low[v];
}
}
else if(in[v] && Low[u] > DFN[v])
{
Low[u] = DFN[v];
}
}
if(DFN[u] == Low[u])
{
scnt ++;
do
{
v = stack[--top];
in[v] = ;
Belong[v] = scnt;
}while(u != v);
}
}
void tpsort()
{
queue<int> que;
memset(first,-,sizeof(first));
int i,v,u;
for(i = ;i < t;i ++)
{
u = Belong[edge[i].u];
v = Belong[edge[i].v];
if(u != v)
{
_add(v,u);
input[u] ++;
}
}
for(i = ;i <= scnt;i ++)
{
if(input[i] == ) que.push(i);
}
while(!que.empty())
{
u = que.front();
que.pop();
if(flag[u] == )
{
flag[u] = ;
flag[op[u]] = ;
}
for(i = first[u];i != -;i = g[i].next)
{
v = g[i].v;
if(--input[v] == ) que.push(v);
}
} }
int main()
{
int n,m,i,u,v;
char s1,s2;
while(scanf("%d%d%*c",&n,&m)!=EOF)
{
if(n == &&m == ) break;
CL();
for(i = ;i < m;i ++)
{
scanf("%d%c%*c%d%c%*c",&u,&s1,&v,&s2);
if(s1 == 'w') u = u*;
else u = u* + ;
if(s2 == 'w') v = v*;
else v = v* + ;
if(u != (v^))
{
add(u,v^);
add(v,u^);
}
}
add(,);
for(i = ;i < *n;i ++)
{
if(!DFN[i])
{
Tarjan(i);
}
}
for(i = ;i < n;i ++)
{
if(Belong[*i] == Belong[*i+])
break;
op[Belong[*i]] = Belong[*i+];
op[Belong[*i+]] = Belong[*i];
}
if(i != n)
{
printf("bad luck\n");
continue;
}
tpsort();
int z = ;
for(i = ; i < *n; i++)
{
if(flag[Belong[i]] == && i != )
{
if(z) printf(" ");
z = ;
printf("%d", i/);
if(i% == )
printf("h");
else
printf("w");
}
}
printf("\n");
}
return ;
}

2-Sat问题的更多相关文章

  1. 多边形碰撞 -- SAT方法

    检测凸多边形碰撞的一种简单的方法是SAT(Separating Axis Theorem),即分离轴定理. 原理:将多边形投影到一条向量上,看这两个多边形的投影是否重叠.如果不重叠,则认为这两个多边形 ...

  2. POJ 3678 Katu Puzzle(2 - SAT) - from lanshui_Yang

    Description Katu Puzzle is presented as a directed graph G(V, E) with each edge e(a, b) labeled by a ...

  3. Map Labeler POJ - 2296(2 - sat 具体关系建边)

    题意: 给出n个点  让求这n个点所能建成的正方形的最大边长,要求不覆盖,且这n个点在正方形上或下边的中点位置 解析: 当然是二分,但建图就有点还行..比较难想..行吧...我太垃圾... 2 - s ...

  4. 学习笔记(two sat)

    关于two sat算法 两篇很好的论文由对称性解2-SAT问题(伍昱), 赵爽 2-sat解法浅析(pdf). 一些题目的题解 poj 3207 poj 3678 poj 3683 poj 3648 ...

  5. LA 3211 飞机调度(2—SAT)

    https://vjudge.net/problem/UVALive-3211 题意: 有n架飞机需要着陆,每架飞机都可以选择“早着陆”和“晚着陆”两种方式之一,且必须选择一种,第i架飞机的早着陆时间 ...

  6. HIT 1917 2—SAT

    题目大意:一国有n个党派,每个党派在议会中都有2个代表, 现要组建和平委员会,要从每个党派在议会的代表中选出1人,一共n人组成和平委员会. 已知有一些代表之间存在仇恨,也就是说他们不能同时被选为和平委 ...

  7. 2 - sat 模板(自用)

    2-sat一个变量两种状态符合条件的状态建边找强连通,两两成立1 - n 为第一状态(n + 1) - (n + n) 为第二状态 例题模板 链接一  POJ 3207 Ikki's Story IV ...

  8. SAT考试里最难的数学题? · 三只猫的温暖

    问题 今天无意中在Quora上看到有人贴出来一道号称是SAT里最难的一道数学题,一下子勾起了我的兴趣.于是拿起笔来写写画画,花了差不多十五分钟搞定.觉得有点意思,决定把解题过程记下来.原帖的图太小,我 ...

  9. 世界碰撞算法原理和总结(sat gjk)

    序言 此文出于作者的想法,从各处文章和论文中,总结和设计项目中碰撞结构处理方法.如有其它见解,可以跟作者商讨.(杨子剑,zijian_yang@yeah.net). 在一个世界中,有多个物体,物体可以 ...

  10. hdu 4115 (2—SAT)

    题意:两个人石头剪刀布,一个人的出法已确定,另一个人的出法有一定约束,某两次要相同或者不同,问你第二个人能否全部都不失败. 思路:根据Bob出的情况,我们可以确定每次Alice有两种方案. R与P,S ...

随机推荐

  1. Sicily 1444: Prime Path(BFS)

    题意为给出两个四位素数A.B,每次只能对A的某一位数字进行修改,使它成为另一个四位的素数,问最少经过多少操作,能使A变到B.可以直接进行BFS搜索 #include<bits/stdc++.h& ...

  2. RBAC权限模型

    RBAC 现在大多数的管理系统都是基于RBAC开发的组织机构权限框架.所有的操作都是基于角色(Role)来完成的.我们先从需求的角度出发,来了解关于系统权限管理. 用户A和用户B都属于研发部,我们可以 ...

  3. git+github上传与管理

    1.首先下载并安装git,方便管理github上的代码 https://git-scm.com/downloads 2.然后点击安装好的git bash(注册好自己的github) git confi ...

  4. javascrit原生实现jquery的append()函数

    /** * javascrit原生实现jquery的append()函数 * @param parent * @param text */ function append(parent, text) ...

  5. VS Build目录下各文件的作用

    VS2010中各种类型文件的作用: .sln 相当于VC6中 .dsw    .vcxproj 相当于VC6中 .dsp    .suo 相当于VC6中 .ncb    .vcxproj.filter ...

  6. Markdown基本语法

    Markdown 基本语法记录 # 欢迎使用 Cmd Markdown 编辑阅读器 ------ 我们理解您需要更便捷更高效的工具记录思想,整理笔记.知识,并将其中承载的价值传播给他人,**Cmd M ...

  7. IIS性能提升

    1. 调整IIS 7应用程序池队列长度 由原来的默认1000改为65535. IIS Manager > ApplicationPools > Advanced Settings Queu ...

  8. Mac OS X 上安装 ASP.NET 5

    在Mac OS X Yosemite 10.10.3 中搭建第一个 ASP.NET 5 Web 项目 终于有时间在 Mac 上安装一下 ASP.NET 5,网上有许多教程,但是多数的时间比较早了,版本 ...

  9. ionic使用方法

    windows下安装配置 npm install -g ionic npm install -g cordova ionic start myproject cd myproject ionic pl ...

  10. iOS书写高质量代码之耦合的处理

    原创 2016-12-26 MrPeak MrPeak杂货铺 耦合是每个程序员都必须面对的话题,也是容易被忽视的存在,怎么处理耦合关系到我们最后的代码质量.今天Peak君和大家聊聊耦合这个基本功话题, ...