标签:cnt en vis int 题解 HNOI2012 dfn low P3225
这道题挺难的,可以加深对割点的理解,还有,排列组合好重要了,分连通块,然后乘法原理(加法原理计数什么的)
传送门 https://www.luogu.org/problem/P3225
省选oi题好难啊QAQ
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<vector> #define maxn 10000 using namespace std; vector<int>G[maxn]; void insert(int be, int en) { G[be].push_back(en); } int low[maxn], dfn[maxn], vis[maxn], df; int cnt[maxn]; void tarjan(int root ,int x) { low[x] = dfn[x] = ++df; int chal = 0; for (int i = 0; i < G[x].size(); i++) { int p = G[x][i]; if (!dfn[p]) { tarjan(root, p); chal++; low[x] = min(low[x], low[p]); if (root != x) { if (low[p] >= dfn[x]) { cnt[x] = 1; } } else { if (chal >= 2) { cnt[root] = 1; } } } else { low[x] = min(low[x], dfn[p]); } } } int num, cn; int gp; void dfs(int x) { if (cnt[x]) return; if (vis[x]) return; num++; vis[x] = gp; for (int i = 0; i < G[x].size(); i++) { int p = G[x][i]; if (cnt[p] && vis[p] != gp) { cn++; vis[p] = gp; } dfs(p); } } int main() { int m; int ccc = 0; while (~scanf("%d", &m) && m) { int n = -1; int be, en; ccc++; memset(dfn, 0, sizeof(dfn)); memset(vis, 0, sizeof(vis)); memset(cnt, 0, sizeof(cnt)); for (int i = 0; i < m; i++) { scanf("%d %d", &be, &en); insert(be, en); insert(en, be); n = max(be, n); n = max(en, n); } for (int i = 1; i <= n; i++) { if (!dfn[i]) tarjan(i, i); } long long ans1 = 0, ans2 = 1; for (int i = 1; i <= n; i++) { if (!vis[i] && !cnt[i]) { cn = num = 0; gp++; dfs(i); if (cn == 0) { ans1 += 2; ans2 *= num * (num - 1) / 2; } if (cn == 1) { ans1 += 1; ans2 *= num; } } } printf("Case %d: %lld %lld\n",ccc, ans1, ans2); for (int i = 0; i <= n; i++) G[i].clear(); } return 0; }
标签:cnt,en,vis,int,题解,HNOI2012,dfn,low,P3225 来源: https://www.cnblogs.com/lesning/p/11621628.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。