CodeForces - 553C Love Triangles(二分图)
題目鏈接:點擊查看
題目大意:給出一個圖,每條邊都有一個權值,權值只能為0或1,若權值為0代表兩個點互相憎惡,權值為1代表兩個點互相喜愛,現在規定love三角形為圖中的任意三個點之間的關系,都必須滿足:
問共有多少種方案可以將初始給出的圖滿足上述要求
題目分析:這個題目先是題意被誤解了好久,一開始以為網上大佬的博客會寫題意,結果沒想到翻了四五篇博客,都是互相抄襲的,有點良心的還寫個轉載,沒良心的直接拿走了,一個字不差的直接抄走了,抄就抄吧,啥都沒寫清楚,題意題意沒寫清楚,題解題解沒寫清楚,然后就導致在這個題看題解上浪費了好多時間
這個題其實理解意思后還是蠻簡單的,我盡我所能講我自己的理解和思考都描述出來吧
題意首先說的是任意三點,也就是隨意取三個點都要滿足上面的條件1或條件2,因為條件1和條件2都有一個相同之處,就是a喜愛b,也就是說點a和點b永遠是共同的一方,而對點c,要么是點c與點a和點b對立,要么點c與點a和點b也是朋友,那么我們不妨可以建立兩個集合A和集合B,規定在集合A中的所有點都互相喜愛,在集合B中的所有點也都互相喜愛,但集合A中的點和集合B中的點都互相憎惡,這樣一來點a和點b一定都在同一個集合中,若點c若和點a和點b在同一個集合中則就是條件1,若點c和點a與點b在對立的集合中則就是條件2,這樣題目就轉換為了二分圖的模型了
當然模型的抽象是我參考網上的題解抽象出來的。。
現在問題是在轉換成二分圖模型后該怎么繼續下去呢,其實二分圖二分圖,我們只需要將整個圖最后轉換為分成兩個部分即可,因為題目中會給出一些邊的關系,那么我們就可以模擬二分圖染色問題的思想設計深搜遍歷,并且題目給出的初始圖并不一定是連通圖,我們可以分成一個個獨立的區塊,對于每一個區塊,都可以用二分圖的染色問題來判斷能否滿足條件,若不滿足條件答案一定是0,若所有的區塊都滿足條件我們才可以進行下一步的答案計算
現在我們假設整個圖一共有k個區塊,我們現在想將這k個區塊最后組合成只有兩個部分,換句話說,我們需要將k個區塊分到兩個集合中,現在問題轉換為了將k個區塊分到兩個集合中,能有多少種方案,因為每個區塊都可以放到集合A中或集合B中,也就是每個區塊都有兩種情況,所以k個區塊總的一共有2^k種情況,但因為集合A和集合B是相同的,無區別的兩個集合,所以最后答案應該除以2,這樣最終答案就是2^(k-1)了,用快速冪算一下答案即可
代碼:
#include<iostream> #include<cstdlib> #include<string> #include<cstring> #include<cstdio> #include<algorithm> #include<climits> #include<cmath> #include<cctype> #include<stack> #include<queue> #include<list> #include<vector> #include<set> #include<map> #include<sstream> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1e5+100;const int mod=1e9+7;struct Node {int to,w;Node(int TO,int W){w=W;to=TO;} };vector<Node>node[N];int vis[N];int q_pow(int a,int b) {int ans=1;while(b){if(b&1)ans=1LL*ans*a%mod;a=1LL*a*a%mod;b>>=1;}return ans; }bool dfs(int u,int color)//將整個區塊染色 {vis[u]=color;//當前點染色for(auto i:node[u])//遍歷與點u相連的所有邊{int v=i.to;int w=i.w;if(vis[v]==-1)//若子節點沒被染色{if(w&&!dfs(v,color))//如果是朋友,就給子節點染上相同的顏色return false;else if(!w&&!dfs(v,!color))//如果是敵人,就給子節點染上不同的顏色return false;}else//如果子節點有顏色{if(w&&vis[v]!=color)//判斷一下子節點與父節點顏色和邊權是否沖突return false;else if(!w&&vis[v]==color)//同上return false;}}return true; }int main() { // freopen("input.txt","r",stdin); // ios::sync_with_stdio(false);memset(vis,-1,sizeof(vis));int n,m;scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){int u,v,w;scanf("%d%d%d",&u,&v,&w);node[u].push_back(Node(v,w));node[v].push_back(Node(u,w));}int ans=0;for(int i=1;i<=n;i++)//找找有多少個區塊{if(vis[i]==-1)//若當前區塊沒被遍歷過{if(dfs(i,0))//若當前區塊滿足二分圖染色情況,答案加一ans++;else//只要有一個區塊不滿足,則答案為0return 0*printf("0");}}printf("%d\n",q_pow(2,ans-1));return 0; }?
總結
以上是生活随笔為你收集整理的CodeForces - 553C Love Triangles(二分图)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CodeForces - 765D Ar
- 下一篇: HDU - 2444 The Accom