• 原始生物


    https://loj.ac/problem/10112

    题目描述

      给出n个约束条件((l,r)),在S这个序列中存在连续的两个数是(l)(r),求满足这些条件的序列的最短长度。

    思路

      我们考虑以((l,r))作为一条单向边,表示(l)后需要加(r),因此对于整个图来说,如果它是连通的,那么就是欧拉回路的长度。但图如果不连通,我么就要考虑加最少的边使得图连通并且存在欧拉回路。有向图存在欧拉回路的条件是每个节点的入度等于出度,我们考虑对于单个连通块内,如果要使得这个连通分量内存在欧拉回路,至少要连从(u)连出(in[u]-out[u])条边(统计一个的差即可,因为总入度等于总出度),所以累加起来即为满足这个连通分量需要加的边数,我们计为(a[i])

      那么对于每个非孤立点的连通分量,统计答案时,如果(a[i]≠0),那么就需要额外连(a[i])条边,这个数目可以包括连通块合并;而(a[i]=0),就需要在连出一条边使得连通块之间连通(相应的,为了维护其仍是欧拉图,目标的连通分量也会连出一条边,但这不影响答案的统计,因为目标的分量相当于少连一条入边,多练一条出边)。最后再加上必须的(n)条边就是答案。

    代码

    #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;
    }
    
  • 相关阅读:
    Java实现 LeetCode 130 被围绕的区域
    Java实现 LeetCode 130 被围绕的区域
    Java实现 LeetCode 130 被围绕的区域
    win32创建控件的一些问题
    win32 sdk绘制ListBox控件
    VC++ WIN32 sdk实现按钮自绘详解 之二.
    win32 sdk 列表视图控件绘制
    win32 sdk树形控件的项拖拽实现
    MFC 用gdi绘制填充多边形区域
    vc 按钮自绘
  • 原文地址:https://www.cnblogs.com/fangbozhen/p/11752740.html
Copyright © 2020-2023  润新知