题目链接: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. MYSQL远程登录权限设置(转)

    Mysql默认关闭远程登录权限,如下操作允许用户在任意地点登录: 1. 进入mysql,GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY ...

  2. 如何更改firefox默认搜索引擎?一步搞定!

    由于开发设计的需要,ytkah平时习惯使用firefox作为默认浏览器,火狐浏览器可添加的扩展功能比较,比如firebug.nofollow.seoquake等,还有比较友好的功能就是选中关键词拖动直 ...

  3. MVC中的_viewstart.cshtml(没有设置Layout却引用了布局)

    今天Home视图中新增了一个视图,因为不需要设置Layout就没与管他,但是运行起来一看,自动引用了布局,分析了半天 也没看出是哪的错误? 后来尝试着在area中增加了一个同样的视图就没有问题,比较这 ...

  4. 专注docker安全:Security Scanning

    导读 Docker毫无疑问是近期运维同学们的热点话题,Docker安全也由此倍受重视,Docker Security Scanning 是一款Docker镜像扫描的安全工具,目前已经在Docker C ...

  5. NGUI的部分控件无法更改layer?

    http://momowing.diandian.com/post/2012-09-17/40038835795 今天狗日的遇到这样的问题,这是一个imagebutton:,它的层定义为:,NGUI里 ...

  6. Linux下tomcat服务

    一:Linux下tomcat服务的启动.关闭与错误跟踪,使用PuTTy远程连接到服务器以后,通常通过以下几种方式启动关闭tomcat服务:切换到tomcat主目录下的bin目录(cd usr/loca ...

  7. ZOJ3741 状压DP Eternal Reality

    E - Eternal Reality Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu S ...

  8. nyoj 8

    http://acm.nyist.net/JudgeOnline/problem.php?pid=8 #include<stdio.h> #include<iostream> ...

  9. 初中数学题归纳w

    刷完了一张代数 P1 计算 $\left( \frac{1}{1}-\frac{1}{2}+\frac{1}{3}-\frac{1}{4}+...+\frac{1}{2011}- \frac{1}{2 ...

  10. WAF绕过神器 (过安全狗、智创SQL注入)

    WAF绕过神器 (过安全狗.智创SQL注入) 发布时间:-- :10文章来源:网络文章作者:panni007 点击次数: 次 分享到: QQ空间 QQ微博 新浪微博 开心网 人人网 摘要:起因: by ...