1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| #include <iostream> #include <bits/stdc++.h> #define LOCAL #define MAXN 1020 #define int long long using namespace std; string a, b; map<string, int> name; vector<int> edge[MAXN]; vector<int> rev_edge[MAXN]; vector<int> path; int visit[MAXN]; int group[MAXN]; int t, p, cnt;
void dfs1(int root){ if(visit[root]) return; visit[root] = 1;
for(auto it: edge[root]){ dfs1(it); } path.push_back(root); }
void dfs2(int root, int ancestor){ if(visit[root]) return ;
visit[root] = 1; group[root] = ancestor; for(auto it: rev_edge[root]){ dfs2(it, ancestor); } }
int32_t main() { #ifdef LOCAL freopen("in1.txt", "r", stdin); freopen("out.txt", "w", stdout); #endif while(cin >> p >> t && (t+p)!=0){ cin.ignore(); name.clear(); cnt = 1; for(int i = 0; i < p; i++){ edge[cnt].clear(); rev_edge[cnt].clear();
getline(cin, a); name[a] = cnt++; }
for(int i = 0; i < t; i++){ getline(cin, a); getline(cin, b); edge[name[a]].push_back(name[b]); rev_edge[name[b]].push_back(name[a]); }
memset(visit, 0, sizeof(visit)); path.clear();
for(int i = 1; i < cnt; i++){ if(!visit[i]) dfs1(i); }
int ans = 0; memset(visit, 0, sizeof(visit)); memset(group, 0, sizeof(group)); for(int i = path.size()-1; i >= 0; i--){ if(!visit[path[i]]){ dfs2(path[i], path[i]); ans++; } }
cout << ans << "\n";
} return 0; }
|