zoukankan      html  css  js  c++  java
  • 图论思维题

        题目连接 : https://www.luogu.org/problemnew/show/P1330

        

    曹是一只爱刷街的老曹,暑假期间,他每天都欢快地在阳光大学的校园里刷街。河蟹看到欢快的曹,感到不爽。河蟹决定封锁阳光大学,不让曹刷街。

    阳光大学的校园是一张由N个点构成的无向图,N个点之间由M条道路连接。每只河蟹可以对一个点进行封锁,当某个点被封锁后,与这个点相连的道路就被封锁了,曹就无法在与这些道路上刷街了。非常悲剧的一点是,河蟹是一种不和谐的生物,当两只河蟹封锁了相邻的两个点时,他们会发生冲突。

    询问:最少需要多少只河蟹,可以封锁所有道路并且不发生冲突。

    输入输出格式

    输入格式:

    第一行:两个整数N,M

    接下来M行:每行两个整数A,B,表示点A到点B之间有道路相连。

    输出格式:

    仅一行:如果河蟹无法封锁所有道路,则输出“Impossible”,否则输出一个整数,表示最少需要多少只河蟹。

    输入输出样例

    输入样例#1: 复制
    3 3
    1 2
    1 3
    2 3
    
    输出样例#1: 复制
    Impossible
    
    输入样例#2: 复制
    3 2
    1 2
    2 3
    
    输出样例#2: 复制
    1

    说明

    【数据规模】

    1<=N<=10000,1<=M<=100000,任意两点之间最多有一条道路。

      ac代码 : 

        

    #include<bits/stdc++.h>
    using namespace std;
    typedef struct W_W{
        int to;
        int next;
    }miao;
    miao x[200020];
    int head[200020];
    int cnt;
    void add(int a,int b){
        x[cnt].to=b;
        x[cnt].next=head[a];
        head[a]=cnt++;
    }
    int se[200020];
    int biao[200020]={0};
    int sum[2];
    int dfs(int start,int color){
        if(biao[start]==1&&se[start]==color){
                return 1;
        }
        biao[start]=1;
        if(se[start]==-1){
            se[start]=color;
        }
        else if(se[start]!=color){
            return -1;
        }
        sum[color]++;
        for(int i=head[start];i!=-1;i=x[i].next){
            if(dfs(x[i].to,1-color)==-1){
                return -1;
            }
        }
        return 1;
    }
    int main(){
        int n,m;
        memset(head,-1,sizeof(head));
        scanf("%d %d",&n,&m);
        cnt=0;
        for(int i=1;i<=m;i++){
            int a,b;
            scanf("%d %d",&a,&b);
            add(a,b);
            add(b,a);
        }
        memset(se,-1,sizeof(se));
        int he=0;
        for(int i=1;i<=n;i++){
            sum[0]=0;
            sum[1]=0;
            if(biao[i]==0){
                if(dfs(i,0)==1){
                    he+=min(sum[0],sum[1]);
                }
                else{
                    printf("Impossible
    ");
                    return 0;
                }
            }
        }
        printf("%d
    ",he);
        return 0;
    }

          大致思路   :

              因为每条路只要选一个端点即可(不能选两个因为如果一条边选两个的话就会挨着不符合题意),接下来就是相邻的点不能同时选择,所以产生了一个想法,选择一个点 把他标记为 1

            然后把他相邻的所有点都标记为 0 ,如果在标记的时候发现该点被标记过而且和当前要标记的数冲突,则为不可能,然后怎样求的最小呢,因为一开始的1 是我随即选的而且 图没有冲突,

            使得 1 0可以全部调换而且图依然满足要求,所以我们只要加上min(sum[ 1 ] , sum [ 0 ])即可..  

  • 相关阅读:
    CentOS7如何升级ruby版本
    多线程面试题:现在有T1、T2、T3三个线程,你怎样保证T2在T1执行完后执行,T3在T2执行完后执行?(转载)
    hive举例实现字数统计
    hive单用户模式安装
    hadoop实例:电子商务网站商品推荐系统
    安装hadoop-eclipse-plugin 插件(win7)
    hadoop高可用分布式集群安装HDFS +yarm
    hadoop伪分布式安装(单机版) HDFS +Yarn
    Hadoop理论原理
    小技巧:oracle锁表杀进程
  • 原文地址:https://www.cnblogs.com/fzw1523/p/10274140.html
Copyright © 2011-2022 走看看