C++ P1726 上白泽慧音

来源:互联网 发布:ubuntu anaconda安装 编辑:程序博客网 时间:2024/05/17 04:47

题目:P1726 上白泽慧音

学习了强联通分量(scc),找了个裸题,用tarjan算法AC了,Dalao勿喷啊! -_-||

# include <iostream># include <cstring># include <vector># include <stack>using namespace std;int n, m, scctot, scc[5010], low[5010], dfn[5010], dfntot, maxn, num;vector<int> map[5010];stack<int> s;void tarjan(int u) {low[u] = dfn[u] = ++dfntot; // 访问步数,后面会不断更新low // low就是u或u的子树能够追溯到的最早的栈中节点的次序号s.push(u); // u结点入栈,后面用来找一个强连通分量 for(int i = 0; i < map[u].size(); i++) {int v = map[u][i];if(dfn[v] == 0) { // 当v没有访问过时,再tarjan(v),更新low tarjan(v);low[u] = min(low[u], low[v]);} else if(scc[v] == 0) low[u] = min(low[u], dfn[v]);//当v不在某个强连通分量时,再更新low }if(low[u] == dfn[u]) {scctot++; // 强连通分量计数(第几个) int x = -1, tot = 0; // tot,这个scc有几个节点 while(x != u) { // 头不等于尾时(中间的结点就是一个强连通分量的节点) if(++tot > maxn) maxn = tot, num = scctot; // 主要保存哪个scc中的scctot最多(num) x = s.top();s.pop();scc[x] = scctot; // 在一个scc中的所有节点都是第scctot个 }}}int main() {int u, v, t;cin >> n >> m;while(m--) {cin >> u >> v >> t;map[u].push_back(v);if(t == 2) map[v].push_back(u);    }for(int i = 1; i <= n; i++) if(dfn[i] == 0) tarjan(i); //在没找过的节点再找下去 cout << maxn << endl;for(int i = 1; i <= n; i++) if(scc[i] == num) cout << i << " "; // 找到num,输出 return 0;}



0 0
原创粉丝点击