题意抽象:1.每一个点都只有一进一出,也就是他一定自己成环或者和别人一起成环。
2.舒适度计算——当x能到达y的时候,舒适度加一。经过计算,在一个环里面,每一个点的舒适度都为环的总点数N的平方,即n*n
3.题目通过更改两条路的终点,使舒适度MAX。实际上就是找到最大的两个环,改动两条使两个环变成一个环(因为设环1的点数为N,环2的点数为M,所以增加的舒适度为(N+M)( N+M )-N*N-M*M==2NM,所以环越大,最后增加的越大,所以找最大的两个环)。
所以AC代码:
#include <iostream>
#include <algorithm>
#include <string>
#include <math.h>
#include <queue>
#include <cstdio>
#define pie (long double)acos(-1)
#define lld long double
using namespace std;
int n;
const int maxn=100000+10;
int a[maxn]={0};
int visit[maxn]={0};
priority_queue<long long >q;
int temp=0;
int dfs(int i)
{
if(visit[i]==1) return temp;
else
{
temp++;
visit[i]=1;
dfs(a[i]);
// cout<<i<<" "<<temp<<endl;
return temp;
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i=1;i<=n;i++)
{
if(visit[i]==0)
{
temp=0;
q.push(dfs(i));
}
}
if(q.size()>=2)
{
long long x=q.top();
q.pop();
// cout<<x<<endl;
long long y=q.top();
q.pop();
// cout<<y<<endl;
long long ans=(x+y)*(x+y);
while(!q.empty())
{
ans=ans+q.top()*q.top();
q.pop();
}
printf("%I64d\n",ans);
}
else if(q.size()==1)
{
long long x=q.top();
printf("%I64d\n",x*x);
}
return 0;
}
错了两次,一个是因为当情况为“只有一个环”的时候,那么第二次q.push()会失败的~,应该要分类讨论
第二次是因为他最后要算的是总的舒适度,我只算了两个环变成一个环的舒适度。