zoukankan      html  css  js  c++  java
  • 【刷题】BZOJ 2935 [Poi1999]原始生物

    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='')
    {
    	if(x<0)putchar('-'),x=-x;
    	if(x>9)write(x/10);
    	putchar(x%10+'0');
    	if(ch!='')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,'
    ');
    	return 0;
    }
    
  • 相关阅读:
    JVM学习笔记之认识JDK(一)
    C#发送邮件异常:根据验证过程,远程证书无效
    windows下使用mysql双机热备功能
    批处理实现mysql的备份
    WebApi FormData+文件长传 异步+同步实现
    Oracle中已知字段名查询所在的表名
    mstsc遇到CredSSP加密Oracle修正
    使用subgit进行svn迁移至git(branch,tags)
    使用guava进行对字符串的加锁
    使用spring-data-solr做solr客户端
  • 原文地址:https://www.cnblogs.com/hongyj/p/9457371.html
Copyright © 2011-2022 走看看