Luogu1330封锁阳光大学(二分图染色、搜索)

【题干】

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

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

【解题】

二分图染色。

因为可能不连通所以要遍历每个点,记得数组初始化。

学一学换颜色和结束函数的操作。

#include<bits/stdc++.h>
using namespace std;
const int N = 500005;
inline int read() {
    char c = getchar();
    int x = 0, f = 1;
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
    return x * f;
}

int n,m,a,b,len,x,t, ans; 
int head[N],c[N],vis[N];
struct node{
    int v,next;
}e[N];

inline void adde(int u, int v){
    e[++len].next =  head[u];
    head[u] = len;
    e[len].v = v;
}
void dfs(int wqy,int t){
    if(c[wqy] != -1 && c[wqy] != t){
        printf("Impossible");
        exit(0);
    }
    
    if(c[wqy] == t) return ; 
    
    x++;
    c[wqy] = t;
    vis[wqy] = 1;
    for(int i = head[wqy]; i; i = e[i].next)  {
        int v = e[i].v;
        dfs(v,t^1);
    }
}
int main(){
    n = read(), m = read();
    for(register int i = 1; i <= m; ++i){
        a = read(), b = read();
        adde(a,b);
        adde(b,a);
    }
    
    for(int i = 1; i <= n; i++){  //每个点都要遍历因为图可能不连通 
      if(!vis[i]){
          memset(c,-1,sizeof c);
        t = 0, x = 0;
        dfs(i,0);
        t = 0;
        for(register int i = 1; i <= n; ++i)    t += (c[i] == 0);
        ans += min(t,x-t);
      }
      
    }
    printf("%d
",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/phemiku/p/11861795.html