ural1382 直接套用 2SAT模板

缩点 拓扑排序。。。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
//2SAT问题 准确判断矛盾边 不必考虑推出的边是否存在矛盾!!
using namespace std;
const int maxn=(1000+1);
vector<int>po[maxn*2],ps[maxn*2],strong[maxn*2];
bool vis[maxn*2],added[maxn*2][maxn*2];
int n,a[maxn],b[maxn],c[maxn],tot=0,color[maxn*2],du[maxn*2],point[maxn*2];
stack<int>s;
void add(int b,int a)
{
if(added[b][a])return;
else added[b][a]=true;
po[a].push_back(b);
ps[b].push_back(a);
}
void dfs1(int cur,int fa)
{
vis[cur]=true;
for(int i=0;i<po[cur].size();i++)
{
int np=po[cur][i];
if(np==fa||vis[np])continue;
dfs1(np,cur);
}
s.push(cur);
}
void dfs2(int cur,int co,int fa)
{
strong[co].push_back(cur);
color[cur]=co;
for(int i=0;i<ps[cur].size();i++)
{
int np=ps[cur][i];
if(np==fa||(color[np]))continue;
dfs2(np,co,cur);
}
}
void strongconnect()
{
memset(vis,0,sizeof(vis));memset(color,0,sizeof(color));
for(int i=1;i<=n*2;i++)
if(!vis[i])dfs1(i,-1);
tot=1;
while(!s.empty())
{
int np=s.top();
s.pop();
if(color[np])continue;
dfs2(np,tot++,-1);
}
}
bool cmp(int a,int b)
{
return du[a]<du[b];
}
int topo(int ans[])
{
for(int i=1;i<tot;i++)
point[i]=i;
bool anss=1;
for(int i=1;i<tot;i++)
{
sort(point+i,point+tot,cmp);
int np=point[i];
if(du[np]>0)return -1;
if(du[np]==du[point[i+1]]&&i+1<tot)anss=0;
ans[i]=np;
for(int j=0;j<ps[np].size();j++)
du[ps[np][j]]--;
}
}
int main()
{
freopen("t.txt","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d%d",&a[i],&b[i],&c[i]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(i==j)continue;
if(a[i]==a[j])
{
add(j*2,i*2-1);
add(i*2,j*2-1);
}
if(i==b[j])
{
add(i*2,j*2);
add(j*2-1,i*2-1);
}
if(b[i]==b[j])
{
add(i*2-1,j*2);
add(j*2-1,i*2);
}
if((a[i]==c[j]&&i!=b[j]))
{
add(i*2,j*2);
add(j*2-1,i*2-1);
}
}
strongconnect(); for(int i=1;i<tot;i++)
{
memset(vis,0,sizeof(vis));
ps[i].clear();
for(int j=0;j<strong[i].size();j++)
{
int np=strong[i][j];
for(int k=0;k<po[np].size();k++)
{
int nc=color[po[np][k]];
if(nc==i)continue;
if(vis[nc]){continue;}
else{vis[nc]=true;ps[i].push_back(nc);du[nc]++;}
}
}
}
int ans[maxn*2];
topo(ans);
int anss[maxn];
for(int i= tot-1;i>=1;i--)
{
int np=ans[i];
for(int i=0;i<strong[np].size();i++)
{
int npp=strong[np][i];
if(anss[(npp+1)/2]==0) anss[((npp+1)/2)]=(npp+1)%2+1;
}
}
for(int i=1;i<n;i++)
printf("%d ",anss[i]);
printf("%d\n",anss[n]);
return 0;
}

  

Ural 1382 2SAT的更多相关文章

  1. URAL - 1003:Parity (带权并查集&2-sat)

    Now and then you play the following game with your friend. Your friend writes down a sequence consis ...

  2. 【2-SAT】URAL - 2089 - Experienced coach

    题意:给出n对点a,b  要求从没对点中选出一个,且最终选出的点n个数不能存在相同的.输入数据满足每种数最多出现3次,最少出现1次 思路:第i对点的编号2*i, 2*i+1,   因为每个数最多出现3 ...

  3. 2-Sat问题

    二分+2-Sat 判断是否可行 输出字典序最小的解 输出字典序可行解 其实这些都是小问题,最重要的是建图,请看论文. 特殊的建边方式,如果a b是一对,a必须选,那么就是b->a建边. HDU ...

  4. UVALive 4849 String Phone(2-sat、01染色)

    题目一眼看去以为是4-sat... 题意:给n(n<=3000)个黑方块的坐标,保证黑方块没有公共边.对于每个黑方块选一个角作为结点,使得所选结点满足输入的一个无向图.其中距离为曼哈顿距离.输出 ...

  5. POJ 3683 Priest John's Busiest Day (2-SAT)

    题意:有n对新人要在同一天结婚.结婚时间为Ti到Di,这里有时长为Si的一个仪式需要神父出席.神父可以在Ti-(Ti+Si)这段时间出席也可以在(Di-Si)-Si这段时间.问神父能否出席所有仪式,如 ...

  6. UVa 1391 Astronauts (2SAT)

    题意:给出一些宇航员他们的年龄,x是他们的平均年龄,其中A任务只能给年龄大于等于x的人,B任务只能给小于x的人,C任务没有限制.再给出m对人,他们不能同任务.现在要你输出一组符合要求的任务安排. 思路 ...

  7. hdu 3622 Bomb Game(二分+2-SAT)

    Bomb Game Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  8. zoj 3717 - Balloon(2-SAT)

    裸的2-SAT,详见刘汝佳训练指南P-323 不过此题有个特别需要注意的地方:You should promise that there is still no overlap for any two ...

  9. [BZOJ 1997][HNOI2010]Planar(2-SAT)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1997 分析: 考虑每条边是在圈子里面还是圈子外面 所以就变成了2-SAT判定问题了= ...

随机推荐

  1. Codeforces Beta Round #19D(Points)线段树

    D. Points time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...

  2. Spider-Python爬虫之PyQuery基本用法

    1.安装方法 pip install pyquery 2.引用方法 from pyquery import PyQuery as pq 3.简介 pyquery 是类型jquery 的一个专供pyth ...

  3. Maximun product

    Given a sequence of integers S = {S1, S2, ..., Sn}, you shoulddetermine what is the value of the max ...

  4. C51 定时器/计数器 个人笔记

    C51的周期 结构图 两个功能寄存器 51单片机定时/计数器的工作由两个特殊功能寄存器控制.TMOD用于设置其工作方式:TCON用于控制其启动和中断申请. 工作方式寄存器TMOD 其中方式一和方式二常 ...

  5. z_algorithm

    //对于字符串a的每个后缀,匹配它与a的第一个后缀的最长公共前缀,复杂度线性void z_algorithm(char *a,int len) { z[]=len; ,j=,k;i<len;i= ...

  6. Linux下汇编语言学习笔记56 ---

    这是17年暑假学习Linux汇编语言的笔记记录,参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译<汇编语言基于Linux环境>的书,喜欢看原版书的同学可以看<Ass ...

  7. baidu 和 es 使用

    http://www.cnblogs.com/kangoroo/p/8047586.html

  8. SOJ 2785_Binary Partitions

    [题意]将一个数用二进制数表示,求一共有多少种表示方法. [分析]思路一:完全背包 [代码] #include <iostream> #include <cstdio> #in ...

  9. 测试使用markdonw写博客

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

  10. Andorid使用WiFi 连接adb进行调试

    无奈数据线连接常常掉线. 于是寻找wifi连接adb的方法,在github上搜索了一下client的源代码后编译后执行了下,发现能够行得通,于是记录一下. 相应的安卓client源代码在这wifi a ...