二分+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. Intern---Microsoft Academic China Team

    项目二: AEther: 项目 一.项目需求:对搜索关键词进行类别的统计分析,为了后面的entity-rank做准备. 0,各种关键数据统计: 数据量:1个月数据:about 1000T. 1,对IE ...

  2. mysqldump和xtrabackup备份原理实现说明

    背景: MySQL数据库备份分为逻辑备份和物理备份两大类,犹豫到底用那种备份方式的时候先了解下它们的差异: 逻辑备份的特点是:直接生成SQL语句,在恢复的时候执行备份的SQL语句实现数据库数据的重现. ...

  3. ffmpeg-201612[01,08,10,17,21,27,30]-bin.7z

    ESC 退出 0 进度条开关 1 屏幕原始大小 2 屏幕1/2大小 3 屏幕1/3大小 4 屏幕1/4大小 5 屏幕横向放大 20 像素 6 屏幕横向缩小 20 像素 S 下一帧 [ -2秒 ] +2 ...

  4. LeetCode 204 Count Primes

    Problem: Count the number of prime numbers less than a non-negative number, n. Summary: 判断小于某非负数n的质数 ...

  5. C+继承

    // 继承.cpp : Defines the entry point for the console application.// #include "stdafx.h" str ...

  6. GroupJoin和Join的声明及调用

    public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(this IEnumerable& ...

  7. javase-->多线程--线程池

    java的线程池理解 在面向对象编程中,对象创建和销毁是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源.在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收. ...

  8. 爬虫requests模块 2

    会话对象¶ 会话对象让你能够跨请求保持某些参数.它也会在同一个 Session 实例发出的所有请求之间保持 cookie, 期间使用 urllib3 的 connection pooling 功能.所 ...

  9. Oracle SQL的硬解析和软解析

    我们都知道在Oracle中每条SQL语句在执行之前都需要经过解析,这里面又分为软解析和硬解析.在Oracle中存在两种类型的SQL语句,一类为 DDL语句(数据定义语言),他们是从来不会共享使用的,也 ...

  10. 关于python中的字符串编码理解

    python2.x 中中间编码为unicode,一个字符串需要decode为unicode,再encode为其它编码格式(gbk.utf8等) 以gbk转utf8为例: s = "我是字符串 ...