Original biological

https://loj.ac/problem/10112

Title Description

  Given the constraints of n \ ((L, R & lt) \) , this sequence is present in the S number is two consecutive \ (L \) , \ (R & lt \) , seeking to satisfy the minimum length of the sequence of these conditions.

Thinking

  We consider \ ((l, r) \ ) as an unidirectional edge, indicates \ (L \) the need to add \ (R & lt \) , so for the whole graph, if it is connected, so that the Euler the length of the loop. Figure but if none, I consider it necessary to add a minimum of side make the figure connected and there is an Euler tour. Euler conditional loop is present in the directed graph of the degree of each node is equal, we consider for communication within a single block, such that if the communication to the Euler memory component, at least even from \ (U \) connected the \ (in [u] -out [ u] \) edges (a statistical difference can, as always equal to the degree of total), so that it is met when the accumulated communication components need to add a number of edges, we calculated as \ (A [I] \) .

  Then the connected component for each non-outlier statistics when the answer, if \ (A [I] ≠ 0 \) , then even the need for additional \ (a [i] \) edges, this number may include a communication block merger ; and \ (a [I] = 0 \) , it is necessary that even at such an edge block communication between the communication (corresponding, still in order to maintain its Euler, communication components of the target will even out one side, but this does not affect the answer to the statistics, since the components of the target of the equivalent of even a small edge, more practice out of a side). It must be the last plus \ (n \) edges is the answer.

Code

#include <bits/stdc++.h>
using namespace std;
const int N=1100;

int fa[N];
int find(int x)
{
    return fa[x]==x?x:fa[x]=find(fa[x]);
}
void f_union(int x,int y)
{
    int fx=find(x),fy=find(y);
    if(fx!=fy)fa[fx]=fy;
}

int read()
{
    int res=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){res=(res<<3)+(res<<1)+ch-'0';ch=getchar();}
    return res*w;
}

int in[N],out[N],a[N];
bool used[N];
int main() 
{
    int n,m=0;    
    n=read();
    for(int i=1;i<=1000;i++)
        fa[i]=i;
    for(int i=1;i<=n;i++)
    {
        int x=read(),y=read();
        out[x]++;in[y]++;
        m=max(m,max(x,y));
        f_union(x,y);
    }
    for(int i=1;i<=m;i++)
    {
        int x=find(i);
        if(i==find(i)&&in[i]+out[i]>0)used[i]=1;//非孤立点记录且是连通分量的父节点 
        if(in[i]>out[i])
            a[x]+=in[i]-out[i];
    }
    int ans=0;
    for(int i=1;i<=m;i++)
        if(used[i])            //这个点代表着一个连通分量 
        {
            if(a[i]!=0)
                ans+=a[i];
            else ++ans;
        }    
    printf("%d",ans+n);
    return 0;
}

Guess you like

Origin www.cnblogs.com/fangbozhen/p/11752740.html