清華大學演算法訓練營 等式

2021-08-22 08:31:52 字數 1704 閱讀 3635

時間限制:2s,空間256mb

問題描述

n個變數和m個「相等」或「不相等」的約束條件,請你判定是否存在一種賦值方案滿足所有m個約束條件。

輸入第一行乙個整數t,表示資料組數。(t<=100)

接下來會有t組資料,對於每組資料:

第一行是兩個整數n,m,表示變數個數和約束條件的個數。(1<=n,m<=500000)

接下來m行,每行三個整數a,b,e(1<=a,b<=n),表示第a個變數和第b個變數的關係:

保證所有資料的n總和不超過500000。

輸出輸出t行,第i行表示第i組資料的答案。若第i組資料存在一種方案則輸出"yes";否則輸出"no"(不包括引號)。

輸入樣例

2

5 51 2 1

2 3 1

3 4 1

1 4 1

2 5 0

3 31 2 1

2 3 1

1 3 0

輸出樣例
yes

no

樣例解釋

對於第一組資料,有5個約束:

顯然我們可以令:

故第一組資料輸出"yes"。

對於第二組資料,有3個約束:

由前兩個約束可推出變數1=變數3,但第三個約束表明變數1≠變數3,矛盾。

故第二組資料輸出"no"。

#include

using

namespace std;

// ***************== **實現開始 ***************==

const

int n =

300005

;// fanther:每個節點的父親節點

// rank:節點的秩(用於啟發式合併)

int father[n]

,rank[n]

;//查詢節點x所在集合的根

intfind

(int x)

// n:變數個數

// m:約束個數

// a:大小為m的陣列,表示m條約束中的a

// b:大小為m的陣列,表示m條約束中的b

// e:大小為m的陣列,表示m條約束中的e

// 返回值:若能找出一種方案,返回"yes";否則返回"no"

string getanswer

(int n,

int m, vector<

int> a, vector<

int> b, vector<

int> e)

int cnt =0;

for(

int i=

0; i++i)

//將e=1的操作提到e=0的操作前

if(e[i]==1

)for

(int i=

0; i++i)

}// e[i]==1 即 a[i]與b[i]有共同的父親節點

else}}

return

"yes";}

// ***************== **實現結束 ***************==

intmain()

printf

("%s\n"

,getanswer

(n, m, a, b, e)

.c_str()

);}return0;

}

清華大學演算法訓練營 象棋

你有足夠多的象棋 車 在乙個n n的棋盤上你能放多少個 車 呢?注意,所給棋盤上有些位置不能放任何東西。同時,某一行 列 最多只能存在乙個 車 第一行為乙個正整數n。1 n 500 接下來n行,每行包含n個整數,若為0表示這個位置不能放 車 若為1表示這個位置可以放 車 輸出乙個整數,表示最多能放多...

清華大學演算法訓練營 重編碼

重編碼 priority queue 有一篇文章,文章包含 n種單詞,單詞的編號從 1 至 n,第 i 種單詞的出現次數為 w i 現在,我們要用乙個 2 進製串 即只包含 0 或 1 的串 s i 來替換第 i 種單詞,使其滿足如下要求 對於任意的 1 i,j n i j 都有 s i 不是 s ...

清華大學演算法訓練營 序列計數

給定乙個n個整數的序列以及乙個非負整數d,請你輸出這個序列中有多少個連續子串行 長度大於1 滿足該子串行的最大值最小值之差不大於d。如 序列1 2 3中長度大於1的連續子串行有 1 2 2 31 2 3第一行包含兩個整數n,d。1 n 300000,0 d 2000000000 接下來一行包含n個整...