题目链接: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. WCF 客户端解决大数据量传输配置

    1. 服务端返回数据给客户端报错 在客户端配置文件中,主要是配置maxReceivedMessageSize <system.serviceModel> <bindings> ...

  2. struts2拦截器interceptor的三种配置方法

    1.struts2拦截器interceptor的三种配置方法 方法1. 普通配置法 <struts> <package name="struts2" extend ...

  3. win7下virtualbox装linux共享win7文件问题(已测试可用)

    virtualbox这个比较强大,在win7上跑redhat5u4很流畅.os之间共享文件是个大家都很关心的问题,这会直接关系到虚拟机用的爽不爽. 在win7和其上的虚拟机linux之间共享文件也很容 ...

  4. 让chrome浏览器变成在线编辑器

    在大部分人眼里,技术宅给人的印象是沉默寡言,总摸不透他心里想些什么,彼此都保持距离.作为半个程序员,我觉得真正的技术宅大部分时间都在找乐子,鼓捣各种想法,和大部分人的极客心理是一样的,程序员也还爱讲笑 ...

  5. Flume-NG内置计数器(监控)源码级分析

    Flume的内置监控怎么整?这个问题有很多人问.目前了解到的信息是可以使用Cloudera Manager.Ganglia有图形的监控工具,以及从浏览器获取json串,或者自定义向其他监控系统汇报信息 ...

  6. NGUI 新版操作教程

    http://www.tasharen.com/forum/index.php?topic=6754

  7. 如何修改git的当前登录信息

    (文章是从我的个人主页上粘贴过来的,大家也可以访问我的主页 www.iwangzheng.com) 之前用的大师的git登录名,后来开通了自己的,需要换成自己的,其实修改方式很简单. $vim .gi ...

  8. Linux Apache prefork和worker的原理详解

    prefork(多进程,每个进程产生子进程)和worker(多进程,每个进程生成多个线程)    prefork的工作原理是,控制进程在最初建立“StartServers”个子进程后,为了满足MinS ...

  9. FOJ 1205

    Problem 1205 小鼠迷宫问题 Accept: 522    Submit: 1679 Time Limit: 1000 mSec    Memory Limit : 32768 KB Pro ...

  10. FFT(1)

    FFT Complex struct complex{ double re,im; complex(double r,double i){re=r,im=i;} complex(){re=0.0,im ...