Jul 29 2014 解題區►解題區 - UVa UVa 11870 - Antonyms contents 1. Problem2. Sample Output3. Sample Input4. Solution Problem 告訴你那些是同義詞,以及誰與誰是反義詞,最後回報是否有矛盾情況。 Sample Output 12345678910111213141532 2big largesmall tinybig smalltiny huge2 1xyz abcabc defdef xyz1 3fire flamefire iceice waterwater fire Sample Input 123Case 1: YESCase 2: NOCase 3: NO Solution 對於每個詞建立兩個節點 (正反兩種意思的節點),同義詞則對兩個正做連接,只需要對建造反義祠的時候檢查,查詢每次是否會落在相同集合的操作。 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354#include <stdio.h> #include <string.h>#include <map>#include <iostream>using namespace std;int p[2048], rank[2048];int findp(int x) { return p[x] == x ? x : (p[x]=findp(p[x]));}int joint(int x, int y) { x = findp(x), y = findp(y); if(x == y) return 0; if(rank[x] > rank[y]) p[y] = x, rank[x] += rank[y]; else p[x] = y, rank[y] += rank[x]; return 1;}int main() { int testcase, cases = 0, N, M; char s[1024]; scanf("%d", &testcase); while(testcase--) { scanf("%d %d", &N, &M); map<string, int> R; int size = 0; for(int i = 0; i < 2048; i++) p[i] = i, rank[i] = 1; for(int i = 0; i < N; i++) { scanf("%s", s); int &x = R[s]; if(x == 0) x = ++size; scanf("%s", s); int &y = R[s]; if(y == 0) y = ++size; joint(2 * x, 2 * y); } int ret = 1; for(int i = 0; i < M; i++) { scanf("%s", s); int &x = R[s]; if(x == 0) x = ++size; scanf("%s", s); int &y = R[s]; if(y == 0) y = ++size; if(findp(2 * x) == findp(2 * y)) ret = 0; joint(2 * x + 1, 2 * y); joint(2 * y + 1, 2 * x); } printf("Case %d: %s\n", ++cases, ret ? "YES" : "NO"); } return 0;} Newer UVa 11871 - New Land Older UVa 11851 - Celebrity Split