题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=27115

思路:有一个trick要注意:当情况为 2 x y 时,可以推出当y留下时,x也必须留下。然后就是后面的k个限制关系,我们可以3^(k)次方枚举,一旦找到符合条件的就return 。然后就是反向建图,拓扑排序找可行解。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
#include<cmath>
using namespace std;
#define MAXN 2222 int n,m,k;
struct Node{
int tag;
int num[];
}node[]; vector<vector<int> >g,gg,edge; int cnt,bcc_count;
int dfn[MAXN],low[MAXN],color[MAXN];
int degree[MAXN];
bool mark[MAXN];
stack<int>S; void Tarjan(int u)
{
low[u]=dfn[u]=++cnt;
mark[u]=true;
S.push(u);
for(int i=;i<edge[u].size();i++){
int v=edge[u][i];
if(dfn[v]==){
Tarjan(v);
low[u]=min(low[u],low[v]);
}else if(mark[v]){
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u]){
int v;
bcc_count++;
do{
v=S.top();
S.pop();
mark[v]=false;
color[v]=bcc_count;
}while(u!=v);
}
} int opp[MAXN];
bool Check()
{
for(int i=;i<=n;i++){
if(color[i]==color[i+n])return false;
opp[color[i]]=color[i+n];
opp[color[i+n]]=color[i];
}
return true;
} bool Judge()
{
int kk=(int)pow(3.0,k);
for(int i=;i<kk;i++){
for(int j=;j<=*n;j++)edge[j]=g[j];
int j=i,_count=;
while(_count<k){
int id=j%;
int x=node[_count].num[id];
if(node[_count].tag==){
edge[x+n].push_back(x);
}else
edge[x].push_back(x+n);
_count++;
j/=;
}
cnt=bcc_count=;
memset(dfn,,sizeof(dfn));
memset(mark,false,sizeof(mark));
for(int j=;j<=*n;j++)if(dfn[j]==)Tarjan(j);
if(Check())return true;
}
return false;
} int vis[MAXN];
void TopSort()
{
queue<int>que;
for(int i=;i<=bcc_count;i++){
if(degree[i]==)que.push(i);
}
memset(vis,,sizeof(vis));
while(!que.empty()){
int u=que.front();
que.pop();
if(vis[u]==){
vis[u]=;
vis[opp[u]]=-;
}
for(int i=;i<gg[u].size();i++){
int v=gg[u][i];
if(--degree[v]==)que.push(v);
}
}
} vector<int>ans;
void Solve()
{
gg.clear();
gg.resize(*n+);
memset(degree,,sizeof(degree));
for(int u=;u<=*n;u++){
for(int i=;i<edge[u].size();i++){
int v=edge[u][i];
if(color[u]!=color[v]){
gg[color[v]].push_back(color[u]);
degree[color[u]]++;
}
}
}
TopSort();
ans.clear();
for(int i=;i<=n;i++)
if(vis[color[i]]==)ans.push_back(i);
printf("%d",(int)ans.size());
for(int i=;i<(int)ans.size();i++){
printf(" %d",ans[i]);
}
puts(".");
} int main()
{
int _case,x,y,z,tag,t=;
scanf("%d",&_case);
while(_case--){
scanf("%d%d%d",&n,&m,&k);
g.clear();
g.resize(*n+);
edge.clear();
edge.resize(*n+);
while(m--){
scanf("%d%d%d",&tag,&x,&y);
if(tag==)g[x+n].push_back(y),g[y+n].push_back(x);
else if(tag==)g[x+n].push_back(y+n),g[y].push_back(x);
else if(tag==)g[x].push_back(y+n),g[y].push_back(x+n);
else g[x].push_back(y+n),g[y].push_back(x+n),g[x+n].push_back(y),g[y+n].push_back(x);
}
for(int i=;i<k;i++){
scanf("%d%d%d%d",&node[i].tag,&node[i].num[],&node[i].num[],&node[i].num[]);
}
printf("Case %d: ",t++);
if(Judge()){
printf("Possible ");
Solve();
}else
puts("Impossible.");
}
return ;
}

loj 1407(2-sat + 枚举 + 输出一组可行解 )的更多相关文章

  1. poj 3683(2-sat+输出一组可行解)

    题目链接:http://poj.org/problem?id=3683 思路:对于每个结婚仪式,只有在开始或结束时进行这两种选择,我们可以定义xi为真当且仅当在开始时进行.于是我们可以通过时间先后确定 ...

  2. loj 1251(2-sat + 输出一组可行解)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26961 思路:u表示留下,~u表示离开,同理v,对于+u,-v,我 ...

  3. poj 3683 2-sat问题,输出任意一组可行解

    /* 2sat问题 输出任意一组可行解 */ #include<stdio.h> #include<string.h> #include<stdlib.h> #in ...

  4. SAM I AM UVA - 11419(最小顶点覆盖+输出一组解)

    就是棋盘问题输出一组解 https://blog.csdn.net/llx523113241/article/details/47759745 http://www.matrix67.com/blog ...

  5. 2-sat 输出任意一组可行解&拓扑排序+缩点 poj3683

    Priest John's Busiest Day Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8170   Accept ...

  6. loj 1154(最大流+枚举汇点)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26868 思路:拆点,容量为最多能跳的步数,然后设立一个超级源点,源 ...

  7. C语言实现输出一组数字中的所有奇数

    /*第二题*/ #include<stdio.h> //输入186732468 //输出173 //输入12345677 //输出13577 main(){ ;//输入的数字,数字的长度 ...

  8. python应用-表格式输出一组数据

    def main(): names=['关羽','张飞','赵云','马超','貂蝉'] subjects=['语文','数学','Python'] table=[[0 for _ in range( ...

  9. 【C语言】(数组方式)输出一组成绩中的最高分与最低分

    两种不同方式获取最大值与最小值 代码1: #include <stdio.h> int main() { ], sum = , max, min; int i; printf(" ...

随机推荐

  1. SOA面向服务架构简述

    在上篇中我们简单谈了下架构设计中服务层的简单理解,在这里我们将继续服务层的架构,在本节我们将重点在于分布式服务.在分布式系统中表现层和业务逻辑层 并不处于同一物理部署,所以我们必须存在分布式服务,以契 ...

  2. Linux中如何查看文件的最初创建时间

    查看 一个文件的 最初创建时间: Linux中如何查看文件的最初创建时间  linux     目前Linux没有直接查看创建文件的命令,你只能通过文件是否被修改过来进行判断. //查看代码stat  ...

  3. c语言的头文件-不是c++类的头文件?

    下面的概述是参考的这篇文章:http://blog.csdn.net/bingxx11/article/details/7771437 c语言编程中也有,也需要头文件, 头文件不只是C++的类才需要! ...

  4. (9)UI(容器)

    1.基础容器   基础容器可以设置子容器布局.是否裁切子元素.填充颜色.背景图片资源等属性.   使用场景.   在官方示例中,大量使用了基础容器作布局管理,如下面的主界面中,用户名称,钻石和金币就使 ...

  5. HDU 4858 项目管理(邻接表 暴力模拟)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4858 我们建造了一个大项目!这个项目有n个节点,用很多边连接起来,并且这个项目是连通的! 两个节点间可 ...

  6. 我常用的delphi 第三方控件

    转载:http://www.cnblogs.com/xalion/archive/2012/01/09/2317246.html 有网友问我常用的控件及功能.我先大概整理一下,以后会在文章里面碰到时再 ...

  7. 解决ecshop登陆自动退出的莫名现象

    最近在做ecshop的二次开发,程序发布后测试出现一个莫名的问题.点击几次页面后出现session丢失,需要重复登陆:本地怎么测试也都无法重现问题.一开始以为是修改程序的问题,可是怎么找都找不着问题所 ...

  8. Ubuntu下装QQ2014

    1.首先我们需要下载一个 deb的 Wine QQ安装包 qq2014官方下载:http://www.longene.org/download/WineQQ2013SP6-20140102-Longe ...

  9. 【linux】VMware12.0安装

    问题1:安装虚拟机时出现The Microsoft Runtime DLL installer failed to complete 解决: 重新安装,安装失败时不要点击结束,在开始“运行”出输入%t ...

  10. HDU 1521 排列组合 指数型母函数

    排列组合 Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u Submit Status D ...