链接:
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=22649
题意就是求有多少联通的块。(一开始自己脑补成双联通 然后死也过不了样例。
这道题目的读入也是挺恶心的。
#pragma comment(linker, "/STACK:10240000,10240000") #include <algorithm> #include <iostream> #include <sstream> #include <cstring> #include <cstdlib> #include <cstdio> #include <vector> #include <cmath> #include <queue> #include <stack> #include <set> #include <map> #define mod 4294967296 #define MAX 0x3f3f3f3f #define lson o<<1, l, m #define rson o<<1|1, m+1, r #define SZ(x) ((int)ans.size()) #define MAKE make_pair #define INFL 0x3f3f3f3f3f3f3f3fLL #define mem(a) memset(a, 0, sizeof(a)) const double pi = acos(-1.0); const double eps = 1e-9; const int N = 105; const int M = 20005; typedef long long ll; using namespace std; int n, m, T; vector <int> G[N]; int pre[N], iscut[N], bcc[N], dfs_clock, bcc_cnt; int dfs(int u, int fa) { int lowu = pre[u] = ++ dfs_clock; int child = 0; for(int i = 0; i < G[u].size(); i++) { int v = G[u][i]; if(!pre[v]) { child++; int lowv = dfs(v, u); lowu = min(lowu, lowv); if(lowv >= pre[u]) { iscut[u] = 1; } } else if(pre[v] < pre[u] && v != fa) { lowu = min(lowu, pre[v]); } } if(fa < 0 && child == 1) iscut[u] = 0; return lowu; } void find_scc() { mem(pre); mem(iscut); mem(bcc); dfs_clock = bcc_cnt = 0; for(int i = 0; i < n; i++) { if(pre[i] == 0) dfs(i, -1); } } int f[N]; int Find(int x) { return f[x] == x ? x : f[x] = Find(f[x]); } int main() { //freopen("in.txt","r",stdin); cin >> T; getchar();getchar(); int ca = 1; while(T--) { string s; getline(cin, s); n = s[0]-'A'+1; for(int i = 0; i < n; i++) G[i].clear(); for(int i = 0; i < n; i++) { f[i] = i; } while(getline(cin, s) && s != "") { int x = s[0]-'A'; int y = s[1]-'A'; int fa = Find(x); int fb = Find(y); if(fa != fb) { f[fa] = fb; } } int cnt = 0; for(int i = 0; i < n; i++) { if(f[i] == i) cnt++; } if(ca > 1) puts(""); ca++; cout << cnt << endl; } return 0; }
时间: 2024-12-18 10:52:47