poj2553 The Bottom of a Graph--Kosaraju算法 & 缩点 & 强连通分量

来源:互联网 发布:非线性最优化确定参数 编辑:程序博客网 时间:2024/05/01 16:45

原题链接:http://poj.org/problem?id=2553


题意:n个点,m对点的关系,定义link点:一个点u所能到达的点,反过来都能到达u,那么点u就是link点。升序输出所有的link点。


分析:强连通缩点后,找到出度为0的即可,具体为什么,看 给的两个实例。


#define _CRT_SECURE_NO_DEPRECATE #include<iostream>#include<vector>#include<cstring>#include<queue>#include<algorithm>#define INF 99999999using namespace std;int n, m;int cnt;int index[5005];bool mark[5005];int out[5005];vector<int> s;vector<int> c[5005];vector<int> g[5005];vector<int> rg[5005];void dfs1(int x){mark[x] = 1;for (int i = 0; i < g[x].size(); i++)if (!mark[g[x][i]])dfs1(g[x][i]);s.push_back(x);}void dfs2(int x){index[x] = cnt;c[cnt].push_back(x);mark[x] = 1;for (int i = 0; i < rg[x].size(); i++)if (!mark[rg[x][i]])dfs2(rg[x][i]);}void Kosaraju(){for (int i = 1; i <= n; i++){for (int j = 0; j < g[i].size(); j++){int t = g[i][j];if (index[t] != index[i])out[index[i]]++;}}vector<int> t;for (int i = 1; i <= cnt; i++)if (out[i] == 0)for (int j = 0; j < c[i].size(); j++)t.push_back(c[i][j]);sort(t.begin(), t.end());for (int i = 0; i < t.size() - 1; i++)printf("%d ", t[i]);if (t.size())printf("%d", t[t.size() - 1]);printf("\n");}int main(){int u, v;while (scanf("%d", &n) && n){scanf("%d", &m);//initfor (int i = 1; i <= n; i++){g[i].clear();rg[i].clear();s.clear();c[i].clear();memset(mark, 0, sizeof(mark));memset(index, 0, sizeof(index));memset(out, 0, sizeof(out));}//scanffor (int i = 0; i < m; i++){scanf("%d%d", &u, &v);g[u].push_back(v);rg[v].push_back(u);}for (int i = 1; i <= n; i++)if (!mark[i])dfs1(i);memset(mark, 0, sizeof(mark));cnt = 0;for (int i = s.size() - 1; i >= 0; i--){if (!mark[s[i]]){cnt++;dfs2(s[i]);}}Kosaraju();}return 0;}






1 0
原创粉丝点击