zoukankan      html  css  js  c++  java
  • P1330 封锁阳光大学 DFS

      

    题目描述

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

    阳光大学的校园是一张由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,任意两点之间最多有一条道路。

    思路是dfs每个联通块  分别黑白染色 ans+=min(黑,白)  

    70ms

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    #define inf 0x3f3f3f3f
    //////////////////////////////////
    const int N=10000+5;
    int n,m;
    vector<int> edge[N];
    int vis[N];
    int ok;
    int ok1,ok2;
    
    void dfs(int cur,int flag)
    {
        vis[cur]=flag;
        if(flag==1)ok1++;
        else ok2++;
    
        if(edge[cur].size())
        rep(i,0,edge[cur].size()-1)
        {
            int v=edge[cur][i];
            if(vis[v]&&vis[v]!=flag)continue;
            if(vis[v]&&vis[v]==flag){ok=0;return ;}
    
            dfs(v,3-flag);
            if(!ok)return ;
        }
        return ;
    }
    int main()
    {
        RII(n,m);
        rep(i,1,m)
        {
            int a,b;
            RII(a,b);
            edge[a].push_back(b);
            edge[b].push_back(a);
        }
        int ans=0;
        ok=1;
        rep(i,1,n)
        if(!vis[i])
        {
            ok1=0;
            ok2=0;
            dfs(i,1);
            ans+=min(ok1,ok2);
            if(ok==0)
                break;
        }
        if(!ok)printf("Impossible
    ");
        else
        cout<<ans;
        return 0;
    }
    View Code

    用前向星  45ms!!!比vector 快很多

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    #define inf 0x3f3f3f3f
    //////////////////////////////////
    const int N=10000+5;
    int n,m;
    int vis[N];
    int ok,ok1,ok2;
    
    int head[N*20];
    int cnt=1;
    struct node
    {
        int to;
        int nex;
    }edge[N*20];
    
    void add(int a,int b)
    {
        edge[++cnt].to=b;
        edge[cnt].nex=head[a];
        head[a]=cnt;
    }
    
    void dfs(int cur,int flag)
    {
        vis[cur]=flag;
        if(flag==1)ok1++;
        else ok2++;
    
        for(int i=head[cur];i;i=edge[i].nex)
        {
            int v=edge[i].to;
            if(vis[v]&&vis[v]!=flag)continue;
            if(vis[v]&&vis[v]==flag){ok=0;return ;}
    
            dfs(v,3-flag);
            if(!ok)return ;
        }
        return ;
    }
    
    int main()
    {
        RII(n,m);
        rep(i,1,m)
        {
            int a,b;
            RII(a,b);
            add(a,b);
            add(b,a);
        }
        int ans=0;
        ok=1;
        rep(i,1,n)
        if(!vis[i])
        {
            ok1=0;
            ok2=0;
            dfs(i,1);
            ans+=min(ok1,ok2);
            if(ok==0)
                break;
        }
        if(!ok)printf("Impossible
    ");
        else
        cout<<ans;
        return 0;
    }
    View Code
  • 相关阅读:
    操作系统复习
    软件工程复习
    2020字节跳动校园招聘算法方向第二场考试题解(部分)
    【牛客】用两个栈来实现一个队列
    LeetCode 62. 不同路径
    LeetCode 79. 单词搜索
    LeetCode 113. 路径总和 II
    LeetCode 389. 找不同
    【牛客】矩阵交换
    【牛客】KiKi学习了结构体和指针
  • 原文地址:https://www.cnblogs.com/bxd123/p/10751966.html
Copyright © 2011-2022 走看看