题意:

      给你一个递归公式,每多一层就多一个限制,问你最多能递归多少层。

思路:

     先分析每一层的限制 x[a[i]] + x[b[i]] != c[i],这里面x[] = 0,1,c[i] = 0,1,2

如果我们把 x[]=0,1想成取或不取,就是基础的关系,那么这个题目就可以直接抽象成2sat问题,然后我们二分去枚举深度,每次根据2sat的结果判断二分走向,我的2sat用的是双深搜的强连通,用那个t打头的也行,随意,这样这个题目就ok了,对了下面总结下2sat的建图吧,这个题目也能用上。


#include<stdio.h>
#include<string.h>
#include<stack> #define N_node 500 + 10
#define N_edge 100000 + 100

using namespace
std; typedef struct
{
int
to ,next;
}
STAR; STAR E1[N_edge] ,E2[N_edge];
int
list1[N_node] ,list2[N_node] ,tot;
int
Belong[N_node] ,cnt;
int
mark[N_node];
int
A[11000] ,B[11000] ,C[11000];
stack<int>st; void add(int a ,int b)
{

E1[++tot].to = b;
E1[tot].next = list1[a];
list1[a] = tot; E2[tot].to = a;
E2[tot].next = list2[b];
list2[b] = tot;
} void
DFS1(int s)
{

mark[s] = 1;
for(int
k = list1[s] ;k ;k = E1[k].next)
if(!
mark[E1[k].to]) DFS1(E1[k].to);
st.push(s);
} void
DFS2(int s)
{

mark[s] = 1;
Belong[s] = cnt;
for(int
k = list2[s] ;k ;k = E2[k].next)
if(!
mark[E2[k].to]) DFS2(E2[k].to);
} bool
ok(int mid ,int n)
{

memset(list1 ,0 ,sizeof(list1));
memset(list2 ,0 ,sizeof(list2));
tot = 1;
for(int
i = 1 ;i <= mid ;i ++)
{
int
x = A[i] * 2 ,xx = A[i] * 2 + 1;
int
y = B[i] * 2 ,yy = B[i] * 2 + 1;
if(
C[i] == 0) add(xx ,y) ,add(yy ,x);
if(
C[i] == 1) add(x ,y) ,add(y ,x) ,add(xx ,yy) ,add(yy ,xx);
if(
C[i] == 2) add(y ,xx) ,add(x ,yy);
}

memset(mark ,0 ,sizeof(mark));
while(!
st.empty()) st.pop();
for(int
i = 0 ;i < n * 2 ;i ++)
if(!
mark[i]) DFS1(i);
memset(mark ,0 ,sizeof(mark));
cnt = 0;
while(!
st.empty())
{
int
xin = st.top();
st.pop();
if(
mark[xin]) continue;
cnt ++;
DFS2(xin);
}
int
mk = 0;
for(int
i = 0 ;i < n * 2 && !mk ;i += 2)
if(
Belong[i] == Belong[i^1]) mk = 1;
return !
mk;
} int main ()
{
int
t ,n ,m ,i;
scanf("%d" ,&t);
while(
t--)
{

scanf("%d %d" ,&n ,&m);
for(
i = 1 ;i <= m ;i ++)
scanf("%d %d %d" ,&A[i] ,&B[i] ,&C[i]);
int
low ,mid ,up ,ans = 0;
low = 0 ,up = m;
while(
low <= up)
{

mid = (low + up) >> 1;
if(
ok(mid ,n))
ans = mid ,low = mid + 1;
else
up = mid - 1;
}

printf("%d\n" ,ans);
}
return
0;
}

最新文章

  1. 实现PHPCMS手机门户的伪静态
  2. Html.BeginForm
  3. java中如何将字符串数组转换成字符串(转)
  4. VS2010安装失败解决办法
  5. yii2.0 图片上传(摘录)
  6. ruby libmysqlclient.18.dylib
  7. Java 操作MySql数据库
  8. spring中@param和mybatis中@param使用区别
  9. 批量转换cue文件编码
  10. CentOS修复“OpenSSL Heartbleed漏洞”方法
  11. 对XML里的属性或元素进行模糊搜索的方法
  12. java异常处理——finally相关
  13. ES6 迭代器和生成器
  14. Postman 进阶(pre-request scripts&amp;test script)
  15. vue 去除前后空格trim
  16. js计算斐波拉切
  17. C#通过 “枚举数支持在指定类型的集合上进行简单迭代” 的概念获取List的一种方式
  18. NOIP2018复赛获奖分数线及名额分配办法
  19. C#索引器理解
  20. bzoj 4929: 第三题

热门文章

  1. BurpSuite生成快捷方式
  2. pytorch(08)数据模型的读取(2)
  3. $nextTick解决Vue组件卸载在加载合并的问题
  4. iOS 面试秘籍全套
  5. BZOJ_2243 [SDOI2011]染色 【树链剖分+线段树】
  6. 主成分分析 | Principal Components Analysis | PCA
  7. python-类的多态的理解
  8. International Collegiate Programming Contest 2019 Latin American Regional Contests Problem K
  9. POJ3278_Catch That Cow(JAVA语言)
  10. 攻防世界 reverse android-app-100