• 洛谷P1330 封锁阳光大学


    题目链接:https://www.luogu.org/problem/P1330

    题意:一个有n(1000)个点m(10000)条边的无向图,要封锁该图使得每条边都不能用,将一个河蟹部署在点上可使它的相邻边都报废,但相邻的两点不能够同时部署河蟹,求问是否能封锁整个图,如果能的话最少需要多少河蟹

    分析:先看不能的情况,画图稍微分析一下就可以发现只要有奇环就无法封锁。

    然后因为相邻两点不能同时部署,那我们就可以考虑染色了,且一张图要么不能染(奇环),能染的话肯定也只有两种情况,比较较小的即可,奇环的寻址可以直接在找环时判断,因为偶环的话第一次到达和第二次到达染的色是相同的,而奇环不同

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=1e4+7;
    const int N=1e5+7;
    const ll inf=0x3f3f3f3f;
    #define mem0(a) memset(a,0,sizeof(a))
    int nxt[N];
    int head[N];
    int to[N];
    int cnt;
    bool used[maxn];
    int sum[2];
    int col[maxn];
    void add(int u,int v){
        cnt++;
        to[cnt]=v;
        nxt[cnt]=head[u];
        head[u]=cnt;
    }
    bool dfs(int nd,int color){
        if(used[nd]){
            if(col[nd]==color){ 
                return true;
            }
            return false;//其实就是奇环不满足 
        }
        used[nd]=true;
        col[nd]=color;
        sum[color]++;
        for(int i=head[nd];i;i=nxt[i]){
            if(!dfs(to[i],color^1)) return false;//不能继续染色了 
        }
        return true;//说明可以继续染色下去 
    }
    int main(){
        int n,m;scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            int x,y;scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
        }
        int ans=0;
        for(int i=1;i<=n;i++){
            if(used[i])continue;//这个点在之前已经遍历过了 
            sum[0]=sum[1]=0;
            if(!dfs(i,0)){
                printf("Impossible");
                return 0;//直接跳出
            }
            ans+=min(sum[0],sum[1]);//把每个联通子图的最少河蟹数加上 
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    0909 操作系统之音
    实验四 主存空间的分配和回收模拟
    12.9评论5位同学试验三
    实验三 进程调度实验
    实验二 作业调度模拟实验
    实验一DOS报告
    0909 操作系统概述
    实验四 主存空间的分配和回收模拟
    实验三同学讨论
    实验三 进程调度模拟程序
  • 原文地址:https://www.cnblogs.com/qingjiuling/p/11508252.html
Copyright © 2020-2023  润新知