Codeforces 884C Bertown Subway dfs判环

Codeforces 884C 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;
}

 

posted @ 2017-11-01 21:46  #Egoist#  阅读(244)  评论(0编辑  收藏  举报