HDOJ/HDU 3715 2-sat+二分 2010年成都赛区
2011-07-24 02:08
399 查看
//题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3715
题目:
[align=left]Problem Description[/align] 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 m while 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 the procedure may output?
[align=left]Input[/align] 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).
[align=left]Output[/align] For each test case, output the result in a single line.
[align=left]Sample Input[/align]
[align=left]Sample Output[/align]
[align=left]Author[/align] CAO, Peng
[align=left]Source[/align] The 2010 ACM-ICPC Asia Chengdu Regional Contest
[align=left]Recommend[/align] zhouzeyong
题意就不在多说了
回想起当年在场外围观的那一场惊心动魄的区域赛。。如今一年也快过去了。。
我是否达到了当年去参加那次区域赛的学长们的能力。。每每念及此,都感觉到非常大的压力
当年的学长毕业的毕业,退役的退役,今年终于轮到我们这一届
2009级的站出来了。。
先说说这个题目。
这个题,先开始看到的时候不知到如何下手,后来看到x的取值仅仅就只有1,0两种情况,而且c的取值也仅仅只有0,1,2
三种取值,于是诱导我们想到了判断可行性的2-sat
但是2-sat仅仅只是判断了可行性,但是我们要求的是输出最大深度。
故我们可以去枚举每一个可能的深度。当然如果直接从0到m进行线性的枚举,然后每次tarjan求强联通,肯定会超时超到爆。。。
所以标准的方法是利用二分答案的方法。利用2-sat来验证可行性。这样大大优化了程序的速度。
建图的方法:
令a=0,a'=1,b=0,b'=1
if(c[i]==0)那么a和b必然矛盾,于是连接边:a->b'同理连接b->a'
if(c[i]==1)那么a和b' a'和b必然矛盾,那么连接,a->b,a'->b',b->a,b'->a'
if(c[i]==2)那么a'和b'必然矛盾,于是:a'->b,b'->a
这样我们就连好了一副图。于是在对着个图进行强连通分量判断就可以AC了。
我的代码:
题目:
[align=left]Problem Description[/align] 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 m while 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 the procedure may output?
[align=left]Input[/align] 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).
[align=left]Output[/align] For each test case, output the result in a single line.
[align=left]Sample Input[/align]
3 2 1 0 1 0 2 1 0 0 0 2 2 0 1 0 1 1 2
[align=left]Sample Output[/align]
1 1 2
[align=left]Author[/align] CAO, Peng
[align=left]Source[/align] The 2010 ACM-ICPC Asia Chengdu Regional Contest
[align=left]Recommend[/align] zhouzeyong
题意就不在多说了
回想起当年在场外围观的那一场惊心动魄的区域赛。。如今一年也快过去了。。
我是否达到了当年去参加那次区域赛的学长们的能力。。每每念及此,都感觉到非常大的压力
当年的学长毕业的毕业,退役的退役,今年终于轮到我们这一届
2009级的站出来了。。
先说说这个题目。
这个题,先开始看到的时候不知到如何下手,后来看到x的取值仅仅就只有1,0两种情况,而且c的取值也仅仅只有0,1,2
三种取值,于是诱导我们想到了判断可行性的2-sat
但是2-sat仅仅只是判断了可行性,但是我们要求的是输出最大深度。
故我们可以去枚举每一个可能的深度。当然如果直接从0到m进行线性的枚举,然后每次tarjan求强联通,肯定会超时超到爆。。。
所以标准的方法是利用二分答案的方法。利用2-sat来验证可行性。这样大大优化了程序的速度。
建图的方法:
令a=0,a'=1,b=0,b'=1
if(c[i]==0)那么a和b必然矛盾,于是连接边:a->b'同理连接b->a'
if(c[i]==1)那么a和b' a'和b必然矛盾,那么连接,a->b,a'->b',b->a,b'->a'
if(c[i]==2)那么a'和b'必然矛盾,于是:a'->b,b'->a
这样我们就连好了一副图。于是在对着个图进行强连通分量判断就可以AC了。
我的代码:
#include<stdio.h> #include<algorithm> #include<string.h> #include<vector> #include<stack> #define maxn 20005 using namespace std; int Index,cnt; int a[maxn],b[maxn],c[maxn]; vector<int>map[maxn]; int belong[maxn],dfn[maxn],low[maxn]; bool used[maxn],instack[maxn]; stack<int>s; void init(int n) { int i; for(i=0;i<=2*n;i++) map[i].clear(); while(!s.empty()) s.pop(); memset(used,0,sizeof(used)); memset(instack,0,sizeof(instack)); memset(dfn,-1,sizeof(dfn)); memset(belong,0,sizeof(belong)); memset(low,0,sizeof(low)); cnt=0,Index=0; } void build_map(int mid,int n) { int i; init(n); for(i=1;i<=mid;i++) { if(c[i]==0) { map[a[i]].push_back(b[i]+n); map[b[i]].push_back(a[i]+n); } if(c[i]==1) { map[a[i]].push_back(b[i]); map[b[i]].push_back(a[i]); map[a[i]+n].push_back(b[i]+n); map[b[i]+n].push_back(a[i]+n); } if(c[i]==2) { map[a[i]+n].push_back(b[i]); map[b[i]+n].push_back(a[i]); } } } int min(int a,int b) { if(a>b) return b; else return a; } void tarjan(int u) { int i,v; Index++; dfn[u]=Index; low[u]=Index; used[u]=true; instack[u]=true; s.push(u); for(i=0;i<map[u].size();i++) { v=map[u][i]; if(!used[v]) { tarjan(v); low[u]=min(low[u],low[v]); } else if(instack[v]) { low[u]=min(low[u],dfn[v]); } } if(dfn[u]==low[u]) { cnt++; do { v=s.top(); s.pop(); belong[v]=cnt; instack[v]=false; } while(u!=v); } } bool judge(int n,int m,int mid) { int i; build_map(mid,n); for(i=0;i<2*n;i++) if(dfn[i]==-1) tarjan(i); for(i=0;i<n;i++) { if(belong[i]==belong[i+n]) return false; } return true; } void solve(int n,int m) { int left,right,mid,ans; left=0,right=m; while(left<=right) { mid=(left+right)>>1; if(judge(n,m,mid)) { ans=mid; left=mid+1; } else right=mid-1; } printf("%d\n",ans); } int main() { int t,i,n,m; 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]); solve(n,m); } return 0; }
相关文章推荐
- HDOJ 3715 - Go Deeper 二分+2-sat判断
- HDU 4465 HDOJ Candy 2012ACM亚洲赛成都赛区B题
- hdoj 3715 Go Deeper 【2-sat 判断可行解 + 二分】
- hdu 3714 Error Curves 2010年成都赛区
- hdu 3715(二分+2-sat)
- HDOJ3715-Go Deeper二分+2-sat解题报告
- HDU 3715 Go Deeper(2-SAT + 二分判定)
- hdu 4033 2011成都赛区网络赛 余弦定理+二分 **
- hdu 3715 2-sat + 二分
- HDU 3715 Go Deeper 二分 + 2-sat
- HDU 4473 HDOJ Exam 2012ACM亚洲赛成都赛区J题
- HDU 4474 HDOJ Yet Another Multiple Problem 2012ACM亚洲赛成都赛区K题
- HDU 3715 Go Deeper(2-SAT + 二分)
- HDU 3715 Go Deeper【2-SAT+二分】
- HDOJ/HDU 3622 二分+2-sat 天津网络赛
- hdu 3715(2-sat入门题目)2010成都现场赛1007题
- hdu 3715 Go Deeper(二分+2-sat判定)
- HDU 3715 Go Deeper 2-SAT 二分答案
- HDU 4474 HDOJ Yet Another Multiple Problem 2012ACM亚洲赛成都赛区K题
- HDU 4466 HDOJ Triangle 2012ACM亚洲赛成都赛区C题