【usaco-Liars and Truth Tellers, 2013 Jan真假奶牛】并查集
2016-10-28 10:31
357 查看
题解:
原先我看错题了,以为是任意选择k个使得它们不矛盾。
这样的话怎么做呢?我想M^2判断,把它们分成若干个集合,集合里面两两不矛盾这个集合里所有的话就不矛盾了。
但是这样是错的。为什么呢?
每一句话实质上都是说明了某两个点同真假或者不同真假。并非两两不矛盾它们就不矛盾,可能是合起来才矛盾。
后来发现题目说的是前k个。。
那么我们就可以像上图一样连边,用并查集判断,如果一个点为真或为假时它的祖先相同,则矛盾了。
代码:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #include<queue> 7 #include<cmath> 8 #include<set> 9 using namespace std; 10 11 const int N=2*1100,M=11000; 12 int n,m,fa ; 13 char s[10]; 14 15 int findfa(int x) 16 { 17 if(fa[x]==x) return x; 18 return findfa(fa[x]); 19 } 20 21 int main() 22 { 23 // freopen("a.in","r",stdin); 24 freopen("truth.in","r",stdin); 25 freopen("truth.out","w",stdout); 26 scanf("%d%d",&n,&m); 27 for(int i=1;i<=2*n;i++) fa[i]=i; 28 int x,y,k=0,bk=1; 29 for(int i=1;i<=m;i++) 30 { 31 scanf("%d%d",&x,&y); 32 scanf("%s",s); 33 if(s[0]=='L') 34 { 35 fa[findfa(x)]=findfa(n+y); 36 fa[findfa(n+x)]=findfa(y); 37 } 38 else 39 { 40 fa[findfa(x)]=findfa(y); 41 fa[findfa(n+x)]=findfa(n+y); 42 } 43 if(findfa(y)==findfa(n+y)) bk=0; 44 if(bk) k++; 45 } 46 printf("%d\n",k); 47 return 0; 48 }
相关文章推荐
- [USACO2013 Jan]Liars and Truth Tellers真假奶牛
- 【USACO】2013 Jan Liars and Truth Tellers 真假奶牛
- BSOJ 4208 -- 【USACO 2013 Jan】奶牛队列
- [usaco]2013-jan Liars and Truth Tellers 真假奶牛
- [Usaco2013 Jan] Square Overlap
- Bzoj 1612: [Usaco2008 Jan]Cow Contest奶牛的比赛 传递闭包,bitset
- [bzoj 3048] [Usaco2013 Jan]Cow Lineup
- 【USACO 2013 January Gold】奶牛排队
- bzoj 3049: [Usaco2013 Jan]Island Travels
- [BZOJ3050][Usaco2013 Jan]Seating(线段树)
- BZOJ 1612: [Usaco2008 Jan]Cow Contest奶牛的比赛
- 【BZOJ】1654: [Usaco2006 Jan]The Cow Prom 奶牛舞会(tarjan)
- 【BZOJ】1654: [Usaco2006 Jan]The Cow Prom 奶牛舞会
- bzoj1655 [Usaco2006 Jan] Dollar Dayz 奶牛商店
- |BZOJ 1654|强连通分量|[Usaco2006 Jan]The Cow Prom 奶牛舞会
- bzoj1655 [Usaco2006 Jan] Dollar Dayz 奶牛商店(完全背包+高精)
- bzoj 2199: [Usaco2011 Jan]奶牛议会
- BZOJ 1612: [Usaco2008 Jan]Cow Contest奶牛的比赛
- BZOJ 1635: [Usaco2006 Jan]The Cow Prom 奶牛舞会 tarjan
- 【USACO 2013 March Gold】奶牛逃跑