loj 1407(2-sat + 枚举 + 输出一组可行解 )
题目链接: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 + 枚举 + 输出一组可行解 )的更多相关文章
- poj 3683(2-sat+输出一组可行解)
题目链接:http://poj.org/problem?id=3683 思路:对于每个结婚仪式,只有在开始或结束时进行这两种选择,我们可以定义xi为真当且仅当在开始时进行.于是我们可以通过时间先后确定 ...
- loj 1251(2-sat + 输出一组可行解)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26961 思路:u表示留下,~u表示离开,同理v,对于+u,-v,我 ...
- poj 3683 2-sat问题,输出任意一组可行解
/* 2sat问题 输出任意一组可行解 */ #include<stdio.h> #include<string.h> #include<stdlib.h> #in ...
- SAM I AM UVA - 11419(最小顶点覆盖+输出一组解)
就是棋盘问题输出一组解 https://blog.csdn.net/llx523113241/article/details/47759745 http://www.matrix67.com/blog ...
- 2-sat 输出任意一组可行解&拓扑排序+缩点 poj3683
Priest John's Busiest Day Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 8170 Accept ...
- loj 1154(最大流+枚举汇点)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26868 思路:拆点,容量为最多能跳的步数,然后设立一个超级源点,源 ...
- C语言实现输出一组数字中的所有奇数
/*第二题*/ #include<stdio.h> //输入186732468 //输出173 //输入12345677 //输出13577 main(){ ;//输入的数字,数字的长度 ...
- python应用-表格式输出一组数据
def main(): names=['关羽','张飞','赵云','马超','貂蝉'] subjects=['语文','数学','Python'] table=[[0 for _ in range( ...
- 【C语言】(数组方式)输出一组成绩中的最高分与最低分
两种不同方式获取最大值与最小值 代码1: #include <stdio.h> int main() { ], sum = , max, min; int i; printf(" ...
随机推荐
- Oracle 11g r2 x64 中文乱码解决方案
1.检查服务器编码: 执行SQL语法: select * from v$nls_parameters; 2.设置本地客户端编码: 进入 我的电脑,属性,高级,环境变量,添加2项:LANG=zh_CN. ...
- yum只下载而不安装软件包?
yum本身自带了两个选项, 用来只下载要安装的rpm包, 而并不实际安装包: yum --downloadonly --downloaddir=/root/Desktop rpm-name1 rpm ...
- CMS介绍
CMS介绍 CMS是Content Management System的缩写,意为“内容管理系统”,它具有许多基于模板的优秀设计,可以加快网站开发的速度和减少开发的成本. CMS的功能不仅限于处理文本 ...
- 草根玩微博 中产玩微信 土豪玩什么?支持Yo的iWatch?
<中国新媒体发展报告(2014)>发布了一些新媒体的使用情况数据,25.6%无收入群体人数在玩微博,32.0%的微信用户属于月收入3000~5000元的中产阶层,那么土豪会玩什么新媒体呢? ...
- Java笔记--泛型总结与详解
泛型简介: 在泛型没有出来之前,编写存储对象的数据结构是很不方便的.如果要针对每类型的对象写一个数据结构, 则当需要将其应用到其他对象上时,还需要重写这个数据结构.如果使用了Object类型, ...
- HDU 4857 Couple doubi(找循环节)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4861 解题报告:桌子上有k个球 ,第i个球的价值wi = 1^i+2^i+...+(p-1)^i (m ...
- 第14章 使用DHCP动态管理主机地址
章节简述: DHCP协议服务能够自动化的管理局域网内的主机IP地址,有效的提升IP地址使用率,提高配置效率,减少管理与维护成本. 学习dhcpd服务程序的使用方法并逐条讲解配置参数,完整演示自动化分配 ...
- Vector3.Lerp 插值
Vector3.Lerp 插值 static function Lerp (from : Vector3, to : Vector3, t : float) : Vector3 Description ...
- 获取Ad用户信息
private]; } dt.Rows.Add(dr); } return dt; ...
- eclipse加速之禁用JS、jsp等文件的语法验证,eclipsejs
eclipse加速之禁用JS.jsp等文件的语法验证 去除eclipse的JS验证:将windows->preference->Java Script->Validator-> ...