There are many anime that are about "love triangles": Alice loves Bob, and Charlie loves Bob as well, but Alice hates Charlie. You are thinking about an anime which has n characters. The characters are labeled from 1 to n. Every pair of two characters can either mutually love each other or mutually hate each other (there is no neutral state).
You hate love triangles (A-B are in love and B-C are in love, but A-C hate each other), and you also hate it when nobody is in love. So, considering any three characters, you will be happy if exactly one pair is in love (A and B love each other, and C hates both A and B), or if all three pairs are in love (A loves B, B loves C, C loves A).
You are given a list of m known relationships in the anime. You know for sure that certain pairs love each other, and certain pairs hate each other. You're wondering how many ways you can fill in the remaining relationships so you are happy with every triangle. Two ways are considered different if two characters are in love in one way but hate each other in the other. Print this count modulo1 000 000 007.
The first line of input will contain two integers n, m (3 ≤ n ≤ 100 000, 0 ≤ m ≤ 100 000).
The next m lines will contain the description of the known relationships. The i-th line will contain three integers ai, bi, ci. If ci is 1, then aiand bi are in love, otherwise, they hate each other (1 ≤ ai, bi ≤ n, ai ≠ bi, ).
Each pair of people will be described no more than once.
Print a single integer equal to the number of ways to fill in the remaining pairs so that you are happy with every triangle modulo1 000 000 007.
3 0
4
4 4 1 2 1 2 3 1 3 4 0 4 1 0
1
4 4 1 2 1 2 3 1 3 4 0 4 1 1
0
In the first sample, the four ways are to:
In the second sample, the only possible solution is to make 1 and 3 love each other and 2 and 4 hate each other.
题意是, 给出n个点,m个边,要求满足不存在三角恋的个数,也就是合法图要求任意三点间不存在 a 喜欢 b b 喜欢c,但a讨厌 c,也不存在a b c相互讨厌。如果1看成喜欢,0看成讨厌,也在a b c三点组成的三角形内,只有可能是三个1,或两个0 一个1,才是合法的,这个定义为三角形法则吧。
通过这个规则,就说明了,如果这是一个连通块,如果a喜欢b b喜欢c,则为了满足上面的三角形法则,一定可以推出a也喜欢c(因为如果a讨厌c,不是合法的图),这样一来,喜欢的会构成一个集合,这个集合内任意两个都是喜欢的,相反,如果a讨厌b,则a所在的集合与b所在的集合,任意两点间都是讨厌的(很好证明,因为假如a的集合另一点d,因a - d = 1 a - b = 0,则为了满足上面三角形法则,b-d边一定是0 )。通过上面的分析发现,这个连通块一定是二分图。二分图x 集 y集内是相互喜欢,x y集间是相互讨厌的。只需要用二分图的 0 1 染色,最后没有冲突,这个连通块就是合法的,否则,不存在解,答案为0。
最后一步,通过上面的染色,可以形成k个独立的连通块。这k个独立的连通块通过排列组合,也就是要求把这k个独立的连通块任意分成2堆,总的个数自然是2^(k-1).可以这样理解,第一堆可以先0 1 2 ... k个,总和为c(0,k) + c(1,k) + c(2,k) + . .. + c(k,k) = 2 ^ (k).但第一堆第二堆 是一样的,所以要除以2,总个数就用2^(k-1).在计算的时候,当然也可以用快速二次幂了,这样更快,但有一个简单的方法。初始ans = (mod+1)/2;每次ans = (ans + ans)%mod 计算k次,第一次,则好(ans + ans) % mod 为1 ,所以等价于计算了2^(k-1)出来了。
#define N 100050 #define M 100005 #define maxn 205 #define MOD 1000000007 int n,m,a,b,c,vis[N],ans; vector<pii> p[N]; void DFS(int f){ FI(p[f].size()){ int v = p[f][i].first; int g = p[f][i].second; if(vis[v] == -1){ if(g) vis[v] = vis[f]; else vis[v] = 1 - vis[f]; DFS(v); } if(g){ if(vis[v] != vis[f]) ans = 0; } else { if(vis[v] == vis[f]) ans = 0; } } } int main() { while(S2(n,m)!=EOF) { FI(n) p[i+1].clear(); FI(m){ S2(a,b);S(c); p[a].push_back(make_pair(b,c)); p[b].push_back(make_pair(a,c)); } memset(vis,-1,sizeof(vis)); ans = (MOD + 1)/2; for(int i= 1;i<=n;i++){ if(vis[i] == -1){ ans = (ans + ans)%MOD; vis[i] = 0; DFS(i); } } printf("%d\n",ans); } return 0; }