码迷,mamicode.com
首页 > 其他好文 > 详细

2019 7.6 T2 虫洞

时间:2019-07-06 22:09:22      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:现在   names   hide   getc   避免   etc   read   描述   type   

虫洞(conch)

 【题目描述】

HZY 现在在数轴原点处,她想跑到 2000001 这个点上。听说各路 神犇暑假里都在健♂身,所有 HZY 也想不要只是简单地跑步,于是她 决定在这条数轴上造虫洞,具体的,每次可以任选两个[1, 2000000] 之中的实数点,将它们用虫洞连接起来(为了避免不必要的时空错乱, 这两个点不能是同一个点,并且如果一个点已经和其它的点通过虫洞 相连,那就不能选)。 这样一来,在 HZY 跑步的过程中,一旦碰到了某个虫洞的一个端 口,就会从另一个端口出来,继续向正方向跑。 现在 HZY 已经建造了 n 个虫洞。她还想再建造 m 个虫洞,使得她 在跑步过程中穿过虫洞的次数最多。

 【输入格式】 从文件 conch.in 中读入数据。 第一行一个整数 n,第二行一个整数 m。 接下来 m 行每行两个整数 a, b( a < b )描述一个已有虫洞的两个端 点。

【输出格式】 输出到文件 conch.out 中。 一行一个数表示再建造 m 个虫洞之后,最多的穿越次数。

input
3
1
10 11
1 4
2 3
output
6

input
3
1
1 3
4 6
2 5
output
8

 

n,m<=1000000

 

sol:先暴力走一遍,对于每个走过的虫洞的入口标记为已访问,再把走过的地方也标记为已访问,然后再扫一遍,可以算出没访问的就是一个个的环,每个环有不同贡献,按贡献大小造虫洞,如果m有多的就XJB特判一下

技术图片
#include <bits/stdc++.h>
using namespace std;
typedef int ll;
inline ll read()
{
    ll s=0;
    bool f=0;
    char ch= ;
    while(!isdigit(ch))
    {
        f|=(ch==-); ch=getchar();
    }
    while(isdigit(ch))
    {
        s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
    }
    return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
    if(x<0)
    {
        putchar(-); x=-x;
    }
    if(x<10)
    {
        putchar(x+0); return;
    }
    write(x/10);
    putchar((x%10)+0);
    return;
}
#define W(x) write(x),putchar(‘ ‘)
#define Wl(x) write(x),putchar(‘\n‘)
const int N=2000005;
int n,m,Go[N],ans=0,Sum[N];
bool Vis[N];
inline int Play(int Pos)
{
    int res=0;
    for(;Pos<=2000000&&(!Vis[Pos]);Pos++)
    {
        Vis[Pos]=1;
        if(Go[Pos])
        {
            Pos=Go[Pos]; res++;
        }
    }
    return res;
}
int main()
{
    freopen("conch.in","r",stdin);
    freopen("conch.out","w",stdout);
    int i;
    R(n); R(m);
    for(i=1;i<=n;i++)
    {
        int a,b; R(a); R(b); Go[a]=b; Go[b]=a;
    }
    for(i=1;i<=2000000;i++)
    {
        Vis[i]=1;
        if(Go[i]) {i=Go[i]; ans++;}
    }
    for(i=1;i<=2000000;i++)
    {
        if(!Vis[i]) Sum[++*Sum]=Play(i);
    }
    sort(Sum+1,Sum+*Sum+1);
    for(i=*Sum;i>=1;i--)
    {
        if(m) {ans+=Sum[i]+2; m--;}
    }
    if(m) ans+=(m<<1)-(m&1);
    Wl(ans);
    return 0;
}
/*
input
3
1
10 11
1 4
2 3
output
6

input
3
1
1 3
4 6
2 5
output
8
*/
View Code

 

2019 7.6 T2 虫洞

标签:现在   names   hide   getc   避免   etc   read   描述   type   

原文地址:https://www.cnblogs.com/gaojunonly1/p/11144339.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!