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
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 被忽视型幼儿该怎么办 言语发育障碍脑神经损伤怎么办 5岁幼儿胆子小怎么办 幼儿20天胆子小怎么办 两岁宝宝胆子小怎么办 两岁的宝宝胆子小怎么办 孕中期发烧38度怎么办 小班社会交往教案有垃圾怎么办 两个月婴幼儿哭闹入睡难怎么办 8岁儿童睡觉困难怎么办 做精细动作手抖怎么办 15个月宝宝缺锌怎么办 八个月宝宝有蛔虫怎么办 两个月婴儿缺锌怎么办 婴儿天热出汗多尿少怎么办 婴儿5个月不主动抓东西怎么办 打疫苗吃了辣怎么办 四个月宝宝枕秃怎么办 四个月的孩子缺钙怎么办 小孩张牙齿会发烧怎么办 对节白蜡叶子干了怎么办 刷机字库坏了怎么办 魅蓝返回键失灵怎么办 牙蛀严重且牙根松动怎么办 蛀牙伤到神经了怎么办 给客户发错邮件怎么办外贸 cf没有枪声和脚步声怎么办 穿越火线fps太低怎么办 win10玩cf没有声音怎么办 儿子死了欠的钱怎么办 儿子欠银行的钱怎么办 惹了社会上的混混怎么办 我是五年级惹上混混怎么办 孩子挨欺负家长怎么办幼儿园 孩子被同学欺负不敢上学怎么办 孩子被欺负不敢还手怎么办 2个月的婴儿内热怎么办 孩子把别人打了怎么办 学生在学校被打怎么办 妈和老丈人搞外遇怎么办? 丈人住在双方出资房中怎么办