codeforces #309 553C C. Love Triangles(dfs+ 圖論)
阿新 • • 發佈:2018-12-24
題目連結:
題目大意:
給出n個點,要求構造合法的完全圖,已經給出了一些邊,邊有紅邊和藍邊,其中任意三個點,連成的邊合法的組合有紅紅紅,紅藍藍
問符合要求的完全圖的數量
題目分析:
首先我們考慮三個點,可能存在的合法組合是紅紅紅,紅藍藍,那麼如果給出其中一條邊(x,y)是紅,那麼可以斷定x,y到另外一點的顏色一定相同;
如果是藍色,那麼,x和y到另外一點的顏色一定不同,因此對於有邊相連的一堆點,我們稱為一個連通塊,那麼對於這個連通塊當中點看成是和其中某一點的為dfs的起點,那麼只要確定它到其他點的顏色,因為兩條邊顏色確定後第三條邊顏色是一定的,所以就只能得到一個完全圖,然而如果題中給出了x,y有邊,那麼就可以直接給出(1,x),(1,y)的顏色關係,(建設dfs起點為1),那麼在dfs中,(1,1)一定是紅色,那麼根據顏色關係,可以對其他的點進行染色,存在滿足所有關係的那麼構成一個連通塊,沒有的話整個題就無解。然後分成連通塊之後,對於每個連通塊,只要和其他連通塊建立一條邊,因為兩邊可以確定第三邊,所以其他的邊都變成確定的。所以最後就是連通塊個數k,結果為2^k
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <vector> #define MAX 100007 using namespace std; vector< pair<int,int> > e[MAX]; int vis[MAX]; const int mod = 1e9+7; int ans; void dfs ( int x ) { for ( int i = 0 ; i < e[x].size(); i++ ) { int v = e[x][i].first; int t = e[x][i].second; if ( vis[v] == -1 ) { if ( t == 1 ) vis[v] = vis[x]; else vis[v] = 1 - vis[x]; dfs ( v ); } if ( t == 1 ) { if ( vis[v] != vis[x] ) ans = 0; } else { if ( vis[v] == vis[x] ) ans = 0; } } } int main ( ) { int n,m,a,b,c; while ( ~scanf ( "%d%d" , &n , &m ) ) { for ( int i = 0 ; i < m ; i++ ) { scanf ( "%d%d%d" , &a , &b , &c ); e[a].push_back ( make_pair(b,c) ); e[b].push_back ( make_pair(a,c) ); } ans = (mod+1)/2; memset ( vis , -1 , sizeof ( vis ) ); for ( int i = 1 ; i <= n ; i++ ) { if ( vis[i] == -1 ) { ans = (ans+ans)%mod; vis[i] = 0; dfs (i); } } printf ( "%d\n" , ans ); } }