描述
有n個變數和m個「相等」或「不相等」的約束條件,請你判定是否存在一種賦值方案滿足所有m個約束條件。
輸入第一行乙個整數t,表示資料組數。
接下來會有t組資料,對於每組資料:
第一行是兩個整數n,m,表示變數個數和約束條件的個數。
接下來m行,每行三個整數a,b,e,表示第a個變數和第b個變數的關係:
若e=0則表示第a個變數不等於第b個變數;
若e=1則表示第a個變數等於第b個變數
輸出輸出t行,第i行表示第i組資料的答案。若第i組資料存在一種方案則輸出"yes";否則輸出"no"(不包括引號)。
輸入樣例1
25 5
1 2 1
2 3 1
3 4 1
1 4 1
2 5 0
3 31 2 1
2 3 1
1 3 0
輸出樣例1
yesno
樣例1解釋
一共有2組資料。
對於第一組資料,有5個約束:
變數1=變數2
變數2=變數3
變數3=變數4
變數1=變數4
變數2≠變數5
顯然我們可以令:
變數1=變數2=變數3=變數4=任意乙個數值
變數5=任意乙個和變數2不同的數值
故第一組資料輸出"yes"。 對於第二組資料,有3個約束:
變數1=變數2
變數2=變數3
變數1≠變數3
由前兩個約束可推出變數1=變數3,但第三個約束表明變數1≠變數3,矛盾。
故第二組資料輸出"no"。
限制對於10%的資料,n,m ≤ 5,t ≤ 5;
對於50%的資料,n,m ≤ 1000,t ≤ 10;
對於100%的資料,1 ≤ n ≤ 300000, m ≤ 500000,1 ≤ a,b ≤ n,t ≤ 100。
保證所有資料的n總和與m總和不超過500000。
空間:256 mb
提示[用並查集來維護相等的集合。]
[改編自 noi 2015 day1 t1 程式自動分析]
//#include #include #include #include using namespace std;
// 並查集
// ***************== **實現開始 ***************==
const int n = 300005;
//father:每個節點的父親節點
//rank:節點的秩
int father[n],rank[n];
//查詢節點x所在集合的根
//x:節點x
//返回值:根
int find(int x)
// 給定n個變數以及m個約束,判定是否能找出一種賦值方案滿足這m個約束條件
// n:如題意
// m:如題意
// a:大小為m的陣列,表示m條約束中的a
// b:大小為m的陣列,表示m條約束中的b
// e:大小為m的陣列,表示m條約束中的e
// 返回值:若能找出一種方案,返回"yes";否則返回"no"(不包括引號)。
string getanswer(int n, int m, vectora, vectorb, vectore)
//需要提前操作e=1的資料,將e=1的資料交換至前面
int cnt=0;
for(int i = 0; i < m; ++i)
if(e[i] == 1)
for(int i = 0; i < m; ++i)
}else}}
return "yes";
}// ***************== **實現結束 ***************==
int main()
printf("%s\n", getanswer(n, m, a, b, e).c_str());
}return 0;
}
清華大學演算法訓練營 等式
時間限制 2s,空間256mb 問題描述 n個變數和m個 相等 或 不相等 的約束條件,請你判定是否存在一種賦值方案滿足所有m個約束條件。輸入第一行乙個整數t,表示資料組數。t 100 接下來會有t組資料,對於每組資料 第一行是兩個整數n,m,表示變數個數和約束條件的個數。1 n,m 500000 ...
清華大學演算法訓練營 象棋
你有足夠多的象棋 車 在乙個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 ...