您的位置:首页 > 运维架构

POJ_2186_Popular Cows

2016-04-13 22:28 399 查看
<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;
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: