<pre name="code" class="cpp">#include<iostream> #include<cstdio> #include<sstream> #include<string> #include<vector> #include<list> #include<set> #include<map> #include<stack> #include<queue> #include<algorithm> #include<cmath> #pragma warning(disable:4996) using std::cin; using std::cout; using std::endl; using std::stringstream; using std::string; using std::vector; using std::list; using std::pair; using std::set; using std::multiset; using std::map; using std::multimap; using std::stack; using std::queue; class Graph { public: int vertex;//总结点数 int edge;//总边数 int SCC;//强联通分量数 vector<vector<int> >adjList;//邻接表 vector<pair<int,int> >represent_SCC;//每个强联通分量的代表元素 map<int, int>SCcomponents;//强连同分量 Graph() { vertex = edge = SCC = 0; } //curpath表示搜索的时间 void tarjan_sub(vector<int>&depth, vector<int>&ancestor, stack<int>&Stack, vector<bool>&visited, vector<bool>&inStack, const int &curvertex, int &time) { visited[curvertex] = true; inStack[curvertex] = true; depth[curvertex] = ancestor[curvertex] = time++; Stack.push(curvertex); for (size_t i = 0; i < adjList[curvertex].size(); i++) { if (!visited[adjList[curvertex][i]])//如果邻接点没被访问过 { tarjan_sub(depth, ancestor, Stack, visited, inStack, adjList[curvertex][i], time); ancestor[curvertex] = std::min(ancestor[curvertex], ancestor[adjList[curvertex][i]]); } else if (inStack[adjList[curvertex][i]])//如果邻接点在之前已经被加入堆栈中 { ancestor[curvertex] = std::min(ancestor[curvertex], depth[adjList[curvertex][i]]); } } if (ancestor[curvertex] == depth[curvertex]) { SCC++; int amount = 0; while (true) { amount++; inStack[Stack.top()] = false; SCcomponents.insert({ Stack.top(),curvertex }); if (curvertex == Stack.top()) { Stack.pop(); break; } Stack.pop(); } represent_SCC.push_back({ curvertex,amount }); } } void tarjan_main() { vector<int>depth(vertex + 1, 0), ancestor(vertex + 1, 0); stack<int>Stack; vector<bool>inStack(vertex + 1, false); vector<bool>visited(vertex + 1, false); int time = 1; for (int curvertex = 1; curvertex <= vertex; curvertex++) { if (!visited[curvertex]) { tarjan_sub(depth, ancestor, Stack, visited, inStack, curvertex, time); } } } int getCow() { vector<pair<int, int> >degree(vertex + 1);//first为出度,second为入度 set<pair<int, int> >Set; for (size_t i = 1; i < adjList.size(); i++) { for (size_t j = 0; j < adjList[i].size(); j++) { int initial = SCcomponents.find(i)->second; int terminal = SCcomponents.find(adjList[i][j])->second; if (initial != terminal&&Set.find({ initial,terminal }) == Set.end())//如果该边的两个点处于两个不同的强联通量中 { Set.insert({ initial,terminal }); degree[initial].first++; degree[terminal].second++; } } } bool isFound = false; int cow = 0; for (size_t i = 0; i < represent_SCC.size(); i++) { if (!degree[represent_SCC[i].first].first)//如果奶牛群的出度为0 { if (!isFound) { isFound = true; cow = i; } else { return 0; } } } return represent_SCC[cow].second; } }; int main() { //freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); int n, m; while (cin >> n >> m) { Graph graph; graph.vertex = n; graph.edge = m; graph.adjList.resize(n + 1); for (int i = 1; i <= m; i++) { int first, second; cin >> first >> second; graph.adjList[first].push_back(second); } graph.tarjan_main();//得到图的几个强联通子图 cout<<graph.getCow() << endl; } return 0; }