zoukankan      html  css  js  c++  java
  • 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;
    } 

     

  • 相关阅读:
    原型,原型对象,原型链,构造函数,继承(一)
    暑假闲着没事第一弹:基于Django的长江大学教务处成绩查询系统
    ANDROID自定义视图——onMeasure流程,MeasureSpec详解
    android 中发送短信
    VelocityTracker简介
    Android xml资源文件中@、@android:type、@*、?、@+含义和区别
    android:id="@+id/android:empty属性的用法举例
    Android ProgressBar详解以及自定义
    Android自定义进度条
    布局技巧:使用ViewStub
  • 原文地址:https://www.cnblogs.com/LjwCarrot/p/10739594.html
Copyright © 2011-2022 走看看