首页 > 其他 > 详细

【刷题】BZOJ 2935 [Poi1999]原始生物

时间:2018-08-10 22:42:05      阅读:275      评论:0      收藏:0      [点我收藏+]

Description

原始生物的遗传密码是一个自然数的序列K=(a1,...,an)。原始生物的特征是指在遗传密码中连续出现的数对(l,r),即存在自然数i使得l=ai且r=ai+1。在原始生物的遗传密码中不存在(p,p)形式的特征。

求解任务:

请设计一个程序:

·读入一系列的特征。

·计算包含这些特征的最短的遗传密码。

·将结果输出

Input

第一行是一个整数n ,表示特征的总数。在接下来的n行里,每行都是一对由空格分隔的自然数l 和r ,1 <= l,r <= 1000。数对(l, r)是原始生物的特征之一。输入文件中的特征不会有重复。

Output

唯一一行应该包含一个整数,等于包含了PIE.IN中所有特征的遗传密码的最小长度。

Sample Input

12
2 3
3 9
9 6
8 5
5 7
7 6
4 5
5 1
1 4
4 2
2 8
8 6

Sample Output

15

注:
PIE.IN中的所有特征都包含在以下遗传密码中:
(8, 5, 1, 4, 2, 3, 9, 6, 4, 5, 7, 6, 2, 8, 6)

Solution

将限制建成边,于是题目的意思就变成了对于每一个联通块,找一个路径最短的欧拉回路/欧拉路径
欧拉路径还有最短的说法?!不可能的,所以肯定是定值。最短这个含义是体现在加边上的
考虑一个联通块,如果其本身是存在一个欧拉回路,即奇度数点为0,那么贡献就是边数加一
否则,奇度数点一定是大于0的偶数 \(x\),我们要加一些边使得图存在欧拉路径,还要让加的边最少,所以就是找 \(x-2\) 个点,两两连边,使图存在欧拉路径,这样的贡献就是加了边后的边数
最后依次考虑每个联通块就好了

#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=1000+10;
int n,in[MAXN],out[MAXN],lt,ans,euler[MAXN],cnt,e,beg[MAXN],nex[MAXN*MAXN<<1],to[MAXN*MAXN<<1],vis[MAXN],app[MAXN];
template<typename T> inline void read(T &x)
{
    T data=0,w=1;
    char ch=0;
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')w=-1,ch=getchar();
    while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
    x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{
    if(x<0)putchar('-'),x=-x;
    if(x>9)write(x/10);
    putchar(x%10+'0');
    if(ch!='\0')putchar(ch);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline void insert(int x,int y)
{
    to[++e]=y;
    nex[e]=beg[x];
    beg[x]=e;
}
inline void dfs(int x)
{
    vis[x]=1;
    chkmin(euler[cnt],in[x]==out[x]?1:0);
    for(register int i=beg[x];i;i=nex[i])
        if(!vis[to[i]])dfs(to[i]);
}
int main()
{
    read(n);
    for(register int i=1;i<=n;++i)
    {
        int u,v;read(u);read(v);app[u]=app[v]=1;
        in[v]++;out[u]++;
        insert(u,v);insert(v,u);
        chkmax(lt,u);chkmax(lt,v);
    }
    for(register int i=1;i<=lt;++i)
        if(!vis[i]&&app[i])euler[++cnt]=1,dfs(i);
    for(register int i=1;i<=lt;++i)
        if(app[i])ans+=max(in[i],out[i]);
    for(register int i=1;i<=cnt;++i)ans+=euler[i];
    write(ans,'\n');
    return 0;
}

【刷题】BZOJ 2935 [Poi1999]原始生物

原文:https://www.cnblogs.com/hongyj/p/9457371.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!