Codeforces 884C Bertown Subway dfs判环
题意大概是 给出station i可到达的station pi,最多更改两个可达station,然后判断最多有多少种情况emmm就是起点终点不同的……(x,y),(y,x)是按两种算
根据题意,必然都是环(i->i也算),那么对于每一个环(含m个点),可产生m*m种,而(a+b)2>a2+b2
因此,只要将最大的两个环合并,就可以得到结果
对于判环emmmm我知道的大概就dfs和并查集了……感觉……好像dfs更好写一些,遍历的时候顺便就计数了……
这里用dfs判环(从一个节点开始遍历,遍历到的节点标记vis[]为true,顺便记录一下节点个数,直至遍历到它本身)
biubiu贴
#include<iostream> #include<stdio.h> #include<vector> #include<algorithm> #include<string.h> using namespace std; typedef long long ll; const int N = 1e5+5; int n, p[N]; vector<ll>v; bool vis[N]; int main() { memset(vis, 0, sizeof(vis)); scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", p + i); for (int i = 1; i <= n; i++) { ll cnt = 1; if (vis[i])continue; vis[i] = 1; int x = p[i]; while (x != i) { vis[x] = 1; x = p[x]; cnt++; } v.push_back(cnt); } if (v.size() >= 2) { sort(v.begin(), v.end()); ll ans = v[v.size() - 1] + v[v.size() - 2]; ans = ans *ans; for (int i=0;i<v.size()-2;i++) { ans += v[i] * v[i]; } printf("%lld\n", ans); } else { printf("%lld\n", v[0] * v[0]); } return 0; }