Luo Gu [P3505] TEL-Teleportation

topic

Topic link: https://www.luogu.com.cn/problem/P3505
to a picture, and then ask you as much as possible even edge so that from \ (1 \) to \ (2 \) after at least \ (5 \) edges.

Thinking

Consider how to make the path 1-2 in just five sides. Then certainly \ (1 \ to P \ to X \ to Y \ to Q \ to 2 \) , where \ (P \) and \ (1 \) adjacent, \ (Q \) and \ (2 \) neighbor.
All the points are divided into \ (5 \) sets, respectively, adjacent to the point 1, 2 and adjacent to the point, and a distance of point 2, point 2 and the second distance, and other points.
Then \ (X \) is the distance from point 1 to 2, \ (Y \) point 2 is 2 and the distance.
Set \ (cnt1, cnt2 \) respectively adjacent to the point 1, 2 and adjacent dots, \ (CNT3, CNT4 \) respectively with a distance of point 2, point 2 and the second distance.
Then certainly with the adjacent 1 point twenty-two connected, connected twenty-two and 2 adjacent points, not directly connected to 1 or 2 twenty-two adjacent points is optimal.
Do not look at "other points", then the answer is the path connecting the dots twenty-two + \ (cnt1 \ Times cnt3 + CNT2 \ Times CNT4 is \) .
So we consider "other point" paddled "with a distance of 1 point 2", "2 and 2 from the point of" in. Obviously, sailed into the larger set is better.
So we determined the size of each set, and then obtaining the number of edges connected to each set twenty-two set and the number of adjacent edges, and then subtracting the number of edges in the collection.
Time complexity \ (O (n + m) \)

Code

#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
using namespace std;

const int N=40010,M=2000010;
int n,m,tot,cnt1,cnt2,ans,pos[N],cnt[6],head[N];

struct edge
{
    int next,to;
}e[M];

int read()
{
    int d=0; char ch=getchar();
    while (!isdigit(ch)) ch=getchar();
    while (isdigit(ch)) d=(d<<3)+(d<<1)+ch-48,ch=getchar();
    return d;
}

void add(int from,int to)
{
    e[++tot].to=to;
    e[tot].next=head[from];
    head[from]=tot;
}

int main()
{
    memset(head,-1,sizeof(head));
    n=read(); m=read();
    for (int i=1,x,y;i<=m;i++)
    {
        x=read(); y=read();
        add(x,y); add(y,x);
        if (x==1) pos[y]=1;
        if (y==1) pos[x]=1;
        if (x==2) pos[y]=2;
        if (y==2) pos[x]=2;
    }
    for (int i=1;i<=n;i++)
        if (pos[i]==1 || pos[i]==2)
            for (int j=head[i];~j;j=e[j].next)
                if (e[j].to>2 && !pos[e[j].to]) pos[e[j].to]=pos[i]+2;
    for (int i=3;i<=n;i++)
        if (pos[i]) cnt[pos[i]]++;
    cnt[5]=n-cnt[1]-cnt[2]-2;
    ans=cnt[1]*(cnt[1]-1)/2+cnt[2]*(cnt[2]-1)/2+cnt[5]*(cnt[5]-1)/2;
    ans+=cnt[1]+cnt[2]+cnt[3]*cnt[1]+cnt[4]*cnt[2]+(cnt[5]-cnt[3]-cnt[4])*max(cnt[1],cnt[2]);
    printf("%d",ans-m);
    return 0;
}

Guess you like

Origin www.cnblogs.com/stoorz/p/12182770.html