Go Deeper(2010成都现场赛题)(2-sat)
2014-07-25 00:53
375 查看
G - Go Deeper
Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu
Description
Here is a procedure's pseudocode:
In this code n is an integer. a, b, c and x are 4 arrays of integers. The index of array always starts from 0. Array a and b consist of non-negative integers smaller than n. Array x consists of only 0 and 1. Array c consists of only 0, 1 and 2. The lengths of array a, b and c are mwhile the length of array x is n.
Given the elements of array a, b, and c, when we call the procedure go(0, n , m) what is the maximal possible value does the procedure output?
Input
There are multiple test cases. The first line of input is an integer T (0 < T ≤ 100), indicating the number of test cases. Then T test cases follow. Each case starts with a line of 2 integers n and m (0 < n ≤ 200, 0 < m ≤ 10000). Then m lines of 3 integers follow. The i-th(1 ≤ i ≤m) line of them are ai-1 ,bi-1 and ci-1 (0 ≤ ai-1, bi-1 < n, 0 ≤ ci-1 ≤ 2).
Output
For each test case, output the result in a single line.
Sample Input
Sample Output
View Code
Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu
Description
Here is a procedure's pseudocode:
go(int dep, int n, int m) begin output the value of dep. if dep < m and x[a[dep]] + x[b[dep]] != c[dep] then go(dep + 1, n, m) end
In this code n is an integer. a, b, c and x are 4 arrays of integers. The index of array always starts from 0. Array a and b consist of non-negative integers smaller than n. Array x consists of only 0 and 1. Array c consists of only 0, 1 and 2. The lengths of array a, b and c are mwhile the length of array x is n.
Given the elements of array a, b, and c, when we call the procedure go(0, n , m) what is the maximal possible value does the procedure output?
Input
There are multiple test cases. The first line of input is an integer T (0 < T ≤ 100), indicating the number of test cases. Then T test cases follow. Each case starts with a line of 2 integers n and m (0 < n ≤ 200, 0 < m ≤ 10000). Then m lines of 3 integers follow. The i-th(1 ≤ i ≤m) line of them are ai-1 ,bi-1 and ci-1 (0 ≤ ai-1, bi-1 < n, 0 ≤ ci-1 ≤ 2).
Output
For each test case, output the result in a single line.
Sample Input
3 2 1 0 1 0 2 1 0 0 0 2 2 0 1 0 1 1 2
Sample Output
1 1 2 题目大意: 给定一些方程,x[]数组未知,求前面最多能够有多少方程x[a]+x!=c能够被满足。 其中 c=0,1,2 x[]={0,1} 相当于裸的2sat问题,加上二分 强烈建议阅读 kuangbin大神对2-sat的总结:http://www.cnblogs.com/kuangbin/archive/2012/10/05/2712429.html 总的来说,就是当 a or b 时 连接 a' -> b 与 b' -> a 的边,然后进行强连通判断是否出现 a 与 a' ...在同一个连通分量中,若在则不可能。 建立数a的两个状态,即a与a',相当于x[a]=1 和 x[a']=0 x[a]+x[b]!=0 [b]=> a or b => a'->b 且 a->b' x[a]+x[b]!=1 => (a and b) or (a' and b') == a or b' 且 a' or b => a'->b' 且 b->a 且 a->b 且 b'->a x[a]+x[b]!=2 => a' or b' => a->b' 且 a'->b 按上面来建图判断即可
#include<cstdio> #include<cstring> int e[50000],pd[50000],be[800],ne[50000],all; int dfn[800],low[800],instack[800],belong[800],stack[800],stak,curr,num; int a,b,c,n,m,l,r,mid,flag; void add(int x,int y,int p){ e[++all]=y; pd[all]=p; ne[all]=be[x]; be[x]=all; } void tarjan(int x){ instack[x]=1; stack[++stak]=x; dfn[x]=low[x]=++curr; for(int j=be[x];j!=0;j=ne[j]) if(pd[j]<=mid){ if(!dfn[e[j]]){ tarjan(e[j]); if(low[x]>low[e[j]]) low[x]=low[e[j]]; }else if(instack[e[j]]&&low[x]>low[e[j]]) low[x]=low[e[j]]; } if(dfn[x]==low[x]){ int j; ++num; do{ j=stack[stak--]; instack[j]=0; belong[j]=num; }while(j!=x); } } int solve(){ curr=stak=num=0; memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(instack,0,sizeof(instack)); for(int i=0;i<2*n;i++) if(!dfn[i]) tarjan(i); flag=0; for(int i=0;i<n;i++) if(belong[2*i]==belong[2*i+1]){ flag=1; break; } return flag; } int main() { int tt; scanf("%d",&tt); while(tt--){ scanf("%d%d",&n,&m); all=0; memset(e,0,sizeof(e)); memset(be,0,sizeof(be)); memset(ne,0,sizeof(ne)); memset(pd,0,sizeof(pd)); for(int i=0;i<m;i++){ scanf("%d%d%d",&a,&b,&c); switch (c){ case 0: add(2*a+1,2*b,i); add(2*b+1,2*a,i); break; case 1: add(2*a,2*b,i); add(2*b+1,2*a+1,i); add(2*b,2*a,i); add(2*a+1,2*b+1,i); break; case 2: add(2*a,2*b+1,i); add(2*b,2*a+1,i); break; } } l=0;r=m-1; while(l<r-1){ mid=(l+r)/2; if(solve()) r=mid; else l=mid; } mid=r; if(!solve()) printf("%d\n",r+1); else printf("%d\n",l+1); } return 0; }
View Code
相关文章推荐
- hdu 3715(2-sat入门题目)2010成都现场赛1007题
- Error Curves(2010成都现场赛题)
- hdu 4115(2-SAT) 2011 成都现场赛E题
- HDU - 2476 String painter (区间DP,08成都现场赛题)
- 2-sat(2011年成都现场赛)
- 2011ACM成都赛区现场赛E题 (2-sat) (SPOJ9939)
- [BZOJ1823][JSOI2010]满汉全席(2-SAT)
- 【bzoj1823】[JSOI2010]满汉全席 2-SAT
- bzoj1997[Hnoi2010]Planar 2-SAT
- BZOJ 1823 JSOI 2010 满汉全席 2-SAT
- 2010北京甲骨文全球大会 展会现场花絮
- BZOJ 1997: [Hnoi2010]Planar [2-SAT]
- HDOJ/HDU 3715 2-sat+二分 2010年成都赛区
- 2-SAT——2.0(hdu3715 Go Deeper,The 2010 ACM-ICPC Asia Chengdu Regional Contest)
- 2012ACM/ICPC成都赛区现场赛A题---Browsing History(hdu4464)
- HDU 4112 2011ACM成都现场赛B
- BZOJ 1997 HNOI 2010 Planar 2-SAT
- BZOJ 1823 JSOI 2010 满汉全席 2-SAT
- 2010全国导游大赛总决赛现场调试及比赛抓图(3)