2014-07-29 解題區/解題區 - UVa UVa 11870 - Antonyms contents 1. Problem2. Sample Output3. Sample Input4. Solution Problem告訴你那些是同義詞,以及誰與誰是反義詞,最後回報是否有矛盾情況。 Sample Output12345678910111213141532 2big largesmall tinybig smalltiny huge2 1xyz abcabc defdef xyz1 3fire flamefire iceice waterwater fire Sample Input123Case 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