USACO Network of Schools 解题报告
来源:互联网 发布:医院财务管理优化方案 编辑:程序博客网 时间:2024/06/11 05:48
这道题是看了大神的解释才明白原来是求强连通分量(SCC, strongly connected components):https://www.byvoid.com/blog/usaco-533-schlnet。
GeeksforGeeks上面有求SCC的两种方法,讲得很详细:
http://www.geeksforgeeks.org/strongly-connected-components/
http://www.geeksforgeeks.org/tarjan-algorithm-find-strongly-connected-components/
包括跑两遍DFS中间加一个reverse的比较好理解的,也包括Tarjan的一遍DFS的。这里用的是后者。大神那里是前者。跑一遍DFS做法从时间上看比大神的跑两遍DFS的方法还慢,我估计主要原因是大神用的是array,我这里用的是vector。不过也不是很确定是不是这个原因。但是两遍DFS确实要好想些。
Executing... Test 1: TEST OK [0.003 secs, 3508 KB] Test 2: TEST OK [0.005 secs, 3508 KB] Test 3: TEST OK [0.003 secs, 3508 KB] Test 4: TEST OK [0.005 secs, 3508 KB] Test 5: TEST OK [0.008 secs, 3508 KB] Test 6: TEST OK [0.011 secs, 3508 KB] Test 7: TEST OK [0.008 secs, 3508 KB] Test 8: TEST OK [0.005 secs, 3508 KB] Test 9: TEST OK [0.014 secs, 3508 KB] Test 10: TEST OK [0.005 secs, 3508 KB] Test 11: TEST OK [0.008 secs, 3508 KB]All tests OK.
/* ID: thestor1 LANG: C++ TASK: schlnet */#include <iostream>#include <fstream> #include <cmath> #include <cstdio> #include <cstring> #include <climits> #include <cassert> #include <string> #include <vector> #include <set>#include <map> #include <queue> #include <stack> #include <algorithm>#include <cassert>using namespace std;// A recursive function that finds and prints strongly connected// components using DFS traversal// u --> The vertex to be visited nextvoid SCC(int u, vector<vector<int> > &sccs, vector<int> &dist, vector<int> &low, stack<int> &st, vector<int> &inStack, int ×tamp, const vector<vector<int> > &adjs){ // Initialize discovery time and low valuedist[u] = low[u] = timestamp;timestamp++;st.push(u);inStack[u] = true;for (int i = 0; i < adjs[u].size(); ++i){int v = adjs[u][i];// If v is not visited yet, then recur for itif (dist[v] < 0){SCC(v, sccs, dist, low, st, inStack, timestamp, adjs);low[u] = min(low[u], low[v]);}else if (inStack[v]){//// Update low value of 'u' only of 'v' is still in stack// (i.e. it's a back edge, not cross edge).low[u] = min(low[u], low[v]);}}// head node found, pop the stack and generate an SCCif (dist[u] == low[u]){int v;std::vector<int> scc;while (st.top() != u){v = st.top();// assert(low[v] == low[u]);scc.push_back(v);st.pop();inStack[v] = false;}v = st.top();assert(v == u);scc.push_back(v);st.pop();inStack[v] = false;sccs.push_back(scc);}}int main(){ifstream fin("schlnet.in");ofstream fout("schlnet.out");int N;fin>>N;vector<vector<int> > adjs(N, vector<int>());for (int i = 0; i < N; ++i){int v;fin>>v;while (v != 0){adjs[i].push_back(v - 1);fin>>v;}}fin.close();// for (int i = 0; i < N; ++i)// {// cout<<i<<":";// for (int j = 0; j < adjs[i].size(); ++j)// {// cout<<adjs[i][j]<<"\t";// }// cout<<endl;// }vector<vector<int> > sccs;vector<int> dist(N, -1);vector<int> low(N, -1);stack<int> st;vector<int> inStack(N, false);int timestamp = 0;for (int u = 0; u < N; ++u){if (dist[u] < 0){SCC(u, sccs, dist, low, st, inStack, timestamp, adjs);}}// cout<<"sccs:"<<endl;// for (int i = 0; i < sccs.size(); ++i)// {// for (int j = 0; j < sccs[i].size(); ++j)// {// cout<<sccs[i][j]<<", low: "<<low[sccs[i][j]]<<", dist: "<<dist[sccs[i][j]]<<endl;// }// }if (sccs.size() == 1){fout<<1<<endl;fout<<0<<endl;}else{std::vector<int> sccid(N, 0);for (int i = 0; i < sccs.size(); ++i){for (int j = 0; j < sccs[i].size(); ++j){ sccid[sccs[i][j]] = i;}}// cout << "sccid:" << endl;// for (int i = 0; i < sccid.size(); ++i)// {// cout << i << "," << sccid[i]<<endl;// }// std::vector<std::vector<int> > dense(sccs.size(), std::vector<int>());std::vector<int> in(sccs.size(), 0);std::vector<int> out(sccs.size(), 0);for (int u = 0; u < adjs.size(); ++u){for (int i = 0; i < adjs[u].size(); ++i){// sccid[u], sccid[adjs[u][i]]// dense[sccid[u]].push_back(sccid[adjs[u][i]]);// dense[sccid[adjs[u][i]]].push_back(sccid[u]);if (sccid[u] != sccid[adjs[u][i]]){in[sccid[adjs[u][i]]]++;out[sccid[u]]++;}}}int incnt = 0, outcnt = 0;for (int i = 0; i < sccs.size(); ++i){if (in[i] == 0){incnt++;}if (out[i] == 0){outcnt++;}}fout<<incnt<<endl;fout<<max(incnt, outcnt)<<endl;}fout.close();return 0; }
assert(low[v] == low[u]);这句有时是无法成立的。不知道为啥。
0 0
- USACO Network of Schools 解题报告
- usaco Network of Schools
- USACO 5.3 Network of Schools
- USACO 5.3 Network of Schools
- USACO Section 5.3 Network of Schools
- usaco 5.3.5 Network of Schools
- jzoj1320 USACO-5.3.3Network of Schools
- usaco training 5.3.3 Network of Schools 题解
- USACO Network of Schools(学校网络) ---强连通分量
- poj Network of Schools
- poj1236 - Network of Schools
- Network of Schools
- Network of Schools
- POJ1236 Network of Schools
- poj1236 Network of Schools
- poj1236 Network of Schools
- poj1236 Network of Schools
- poj1236-Network of Schools
- GCD并发队列
- linux命令后台运行
- android Alertdialog.Builder 创建对话框的七种方式
- 1635
- CSS round buttons
- USACO Network of Schools 解题报告
- 多个图片平均分布
- Cheap Louis Vuitton Free Shipping 8GI0j
- Cheap Louis Vuitton Handbags tQHLD
- Cheap Louis Vuitton Handbags hkV3N
- Cheap Louis Vuitton Sale PvAbS
- 【Java.Web】Cookie —— 基础
- SAFEARRAY与SAFEARRAYBOUND的相关知识点
- android开源代码站开通啦!