J. Burnished Security Updates 题解(二分图染色)

题目链接

题目大意

给你\(n(2 \leq n\leq 3\times 10^5)\)个点$1\leq m \leq 3\times 10^5 $条边

要你给一些点染色,使得每条边有且仅有一个点被染色

求最少被染色的点数

题目思路

其实转换一下就会发现就是一个裸的二分图染色

代码

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
typedef long long ll;
typedef pair<double,int> pdi;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int maxn=3e5+5,mod=1e7;
int n,m;
int ans[2];
int col[maxn];
int head[maxn],cnt;
struct edge{
    int to,next;
}e[maxn<<1];
void add(int u,int v){
    e[++cnt]={v,head[u]};
    head[u]=cnt;
}
void dfs(int son,int fa,int flag){
    col[son]=flag;
    ans[flag]++;
    for(int i=head[son];i;i=e[i].next){
        if(e[i].to==fa) continue;
        if(col[e[i].to]!=-1){
            if(col[e[i].to]!=(flag^1)){
                printf("-1\n");
                exit(0);
            }
            continue;
        }
        dfs(e[i].to,son,flag^1);
    }
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1,u,v;i<=m;i++){
        scanf("%d%d",&u,&v);
        add(u,v),add(v,u);
    }
    memset(col,-1,sizeof(col));
    int sum=0;
    for(int i=1;i<=n;i++){
        if(col[i]!=-1) continue;
        ans[0]=ans[1]=0;
        dfs(i,i,1);
        sum+=min(ans[0],ans[1]);
    }
    printf("%d\n",sum);
    return 0;
}

posted @ 2021-03-09 20:41  hunxuewangzi  阅读(75)  评论(0编辑  收藏  举报