hdu3715
hdu3715
题意
给出一个递归的伪代码,当 x[a[dep]] + x[b[dep]] != c[dep],就向下递归,给出a,b,c数组的值 问 dep 最大多少。其中 0 <= c[i] <= 2 ,0 <= x[i] <= 1。
分析
x 取值存在对立关系( 1或0 ),那么可以通过不等式进行建边,有三种情况,
- 当 c[i] = 2 时,有 A and B = 0,即不能全部为真
- 当 c[i] = 1 时,有 A xor B = 0,加起来不能等于1
- 当 c[i] = 0 时,有 A or B != 0
二分m,判断可行性
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<iostream>
using namespace std;
const int MAXN = 5e2 + 10;
const int MAXM = 1e4 + 10;
int n, m;
int vis[MAXN];
int flag[MAXN]; // 所属强连通分量的拓扑序
vector<int> G[MAXN], rG[MAXN]; // 注意初始化
vector<int> vs; // 后序遍历顺序的顶点列表
void addedge(int x, int y)
{
G[x].push_back(y); // 正向图
rG[y].push_back(x); // 反向图
}
void dfs(int u)
{
vis[u] = 1;
for(int i = 0; i < G[u].size(); i++)
{
int v = G[u][i];
if(!vis[v]) dfs(v);
}
vs.push_back(u);
}
void rdfs(int u, int k)
{
vis[u] = 1;
flag[u] = k;
for(int i = 0; i < rG[u].size(); i++)
{
int v = rG[u][i];
if(!vis[v]) rdfs(v, k);
}
}
int scc() // 强连通分量的个数
{
vs.clear();
memset(vis, 0, sizeof vis);
for(int i = 0; i < n; i++)
if(!vis[i]) dfs(i);
memset(vis, 0, sizeof vis);
int k = 0;
for(int i = vs.size() - 1; i >= 0; i--)
if(!vis[vs[i]]) rdfs(vs[i], k++);
return k;
}
bool judge()
{
int N = n;
n = 2 * n;
scc();
n /= 2;
for(int i = 0; i < N; i++)
if(flag[i] == flag[N + i])
return false;
return true;
}
int a[MAXM], b[MAXM], c[MAXM];
void init(int can)
{
for(int i = 0; i < 2 * n; i++) G[i].clear(), rG[i].clear();
for(int i = 0; i <= can; i++) // 注意这里是等号
{
if(c[i] == 2) // A and B = 0
{
addedge(a[i], b[i] + n);
addedge(b[i], a[i] + n);
}
else if(c[i] == 1) // A xor B = 0
{
addedge(a[i], b[i]);
addedge(a[i] + n, b[i] + n);
addedge(b[i], a[i]);
addedge(b[i] + n, a[i] + n);
}
else // A or B != 0
{
addedge(a[i] + n, b[i]);
addedge(b[i] + n, a[i]);
}
}
}
void solve()
{
int l = 0, r = m, mid;
while(l + 1 < r)
{
mid = (l + r) / 2;
init(mid);
if(judge()) l = mid;
else r = mid;
}
printf("%d\n", l + 1); // 注意上面是等号,实际数量要加1
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
scanf("%d%d", &n, &m);
for(int i = 0; i < m; i++) scanf("%d%d%d", &a[i], &b[i], &c[i]);
solve();
}
return 0;
}
hdu3715的更多相关文章
- hdu3715 Go Deeper[二分+2-SAT]/poj2723 Get Luffy Out[二分+2-SAT]
这题转化一下题意就是给一堆形如$a_i + a_j \ne c\quad (a_i\in [0,1],c\in [0,2])$的限制,问从开头开始最多到哪条限制全是有解的. 那么,首先有可二分性,所以 ...
- HDU3715(二分+2-SAT)
Go Deeper Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ...
- hdu3715 2-sat+二分
Go Deeper 题意:确定一个0/1数组(size:n)使得满足最多的条件数.条件在数组a,b,c给出. 吐槽:哎,一水提,还搞了很久!关键是抽象出题目模型(如上的一句话).以后做二sat:有哪些 ...
- hdu3715 二分+2sat+建图
题意: 给你一个递归公式,每多一层就多一个限制,问你最多能递归多少层. 思路: 先分析每一层的限制 x[a[i]] + x[b[i]] != c[i],这里面x[] = 0,1, ...
- 2-SAT算法
参考blog 参考论文 参考论文 题目 & 题解 裸2-SAT poj3683 poj3207 poj3678 poj3648 2-SAT + 二分法 poj2723 poj2749 hdu3 ...
随机推荐
- EasyUI之Hello world(EasyUI的入门学习)
1:创建一个动态web工程: 去官网http://www.jeasyui.net/download/下载官网文档 我去官网下载的最新版本,个人根据自己的需求下载即可.2:在webConte ...
- OutOfMemoryError内存不足
java.lang.OutOfMemoryError内存不足错误.当可用内存不足以让Java虚拟机分配给一个对象时抛出该错误. 造成此错误的原因有一下几个: 1.内存中加载的数据量过于庞大,如一次从数 ...
- kafka入门
1.Kafka独特设计在什么地方?2.Kafka如何搭建及创建topic.发送消息.消费消息?3.如何书写Kafka程序?4.数据传输的事务定义有哪三种?5.Kafka判断一个节点是否活着有哪两个条件 ...
- FOJ 11月月赛题解
抽空在vjudge上做了这套题.剩下FZU 2208数论题不会. FZU 2205 这是个想法题,每次可以在上一次基础上加上边数/2的新边. #include <iostream> #in ...
- Android 性能优化——之图片的优化
Android 性能优化——之图片的优化 在Android性能优化中,我们会发现占内存最大的和对性能影响最大的往往是图片资源,其次是控件资源.相对来说,其他的资源的影响会小一点.这里我就先对图片资源的 ...
- jsp实现仿QQ空间新建多个相册名称,向相册中添加照片
工具:Eclipse,Oracle,smartupload.jar:语言:jsp,Java:数据存储:Oracle. 实现功能介绍: 主要是新建相册,可以建多个相册,在相册中添加多张照片,删除照片,删 ...
- ASP.NET MVC 常用扩展点:过滤器、模型绑定等
一.过滤器(Filter) ASP.NET MVC中的每一个请求,都会分配给对应Controller(以下简称“控制器”)下的特定Action(以下简称“方法”)处理,正常情况下直接在方法里写代码就可 ...
- Vue 项目实战系列 (一)
最近一直在学习Vue,基本的文档看完后就需要进行具体的项目进行练手了,本系列文章主要是将我学习过程记录下来,和大家一起学习交流. 我在git上找到了一个淘票票的Vue项目,项目地址: https:// ...
- Start to write blogs 【开始写博客】
I used to be lazy and wrote no blogs. I used to live at leisure and wasted opportunity. Time flies, ...
- node.js 中回调函数callback(转载),说的很清楚,看一遍就理解了
最近在看 express,满眼看去,到处是以函数作为参数的回调函数的使用.如果这个概念理解不了,nodejs.express 的代码就会看得一塌糊涂.比如: 复制代码 代码如下: app.use(fu ...