• Kattis


    题目传送门:Kattis - hoppers  Hoppers

    题目大意:

    你是一个黑客,现在你发明了一种感染病毒,这种感染病毒能够感染到与该主机相隔一个点的主机。

    存在一个无向图,每个点代表一台主机,每条无向边表示两台主机相连,现在你有个计划是通过感

    染一个电脑让所有电脑感染,你可以为两条电脑之间加边,需要你求出最少加多少条边能够完成计划

    分析:

    我们能够发现奇数环中任何一个点被感染都能够使奇数环中所有的点感染。因此我们可以利用该性质。

    为了满足条件(感染一个点使所有点被感染)存在几种情况:

    1.如果存在不连通的一个奇数环和一个偶数环:需要加一条边,将奇数环和偶数环相连即可

    2.如果存在两个不联通的奇数环:需要加一条边

    3.如果存在两个不连通的偶数环:需要加两条边:一条边将两个偶数环联通,一条边加进任意一个偶数环中

    构成一个奇数环。

    因此我们可以得出这题的解法:通过dfs判断存在多少个联通块,如果存在n个联通块则需要n-1条边将所有联通

    块连接。再每次进行dfs时判断,每个联通块中是否存在奇数环,如果存在奇数环则无需另外加一条边,否则加一条边

    代码:

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<cmath>
    using namespace std;
    const int MAX=500009;
    int n,m,u,v;
    vector<int>G[MAX];
    int vis[MAX];
    int odd=1;
    bool dfs(int u,int val)
    {
        vis[u]=val;
        for(int i=0;i<G[u].size();i++){
            int v=G[u][i];
            if(!vis[v])dfs(v,val+1);
            else if((abs(vis[u]-vis[v])+1)%2!=0)odd=0;        //存在奇数环
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<m;i++){
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        int ans=0;
        for(int i=1;i<=n;i++){
            if(!vis[i]){
                dfs(i,1);
                ans++;        //记录存在多少个联通块 
            }    
        }
        printf("%d
    ",ans-1+odd);
        return 0;
    } 

     

  • 相关阅读:
    易语言软件加VMProtect壳的正确方法
    ghost系统到硬盘完后,重启进入winxp安装的画面变成了蓝屏
    万象客户端设置服务端ip保存在注册表的位置
    php乱码解决
    远程桌面Default.rdp 中各个参数的含义
    关闭自动检测磁盘
    关于collapsed margin(外边距合并)
    position定位
    grunt-replace和grunt-include-replace问题
    关于动态生成dom绑定事件失效的原因
  • 原文地址:https://www.cnblogs.com/LjwCarrot/p/10739594.html
Copyright © 2020-2023  润新知