昨晚ABC的D
查看原帖
昨晚ABC的D
373359
荔枝洗衣机楼主2022/12/18 14:17

关于染色法判定二分图

错误染色代码:

bool dfs(int u,int c){
    color[u] = c;
    c == 1 ? cnt1++ : cnt2++;
    for(int i = h[u]; ~i; i = ne[i]){
        int j = e[i];
        if(color[j] == c) return false;
        if(!color[j]) dfs(j,3-c);
    }
    return true;
}

正确染色代码:

bool dfs(int u,int c){
    color[u] = c;
    c == 1 ? cnt1++ : cnt2++;
    for(int i = h[u]; ~i; i = ne[i]){
        int j = e[i];
        if(color[j] == c) return false;
        if(!color[j] && !dfs(j,3-c)) return false;
    }
    return true;
}

完整正确代码:

#include<iostream>
#include<cstring>
using namespace std;

typedef long long LL;
const int N = 4e5+10;
int n,m;
LL res1,res2,cnt1,cnt2;
int color[N],num[N];
int h[N],ne[N],e[N],idx;

void add_edge(int u,int v){
    e[idx] = v;
    ne[idx] = h[u];
    h[u] = idx++;
}

bool dfs(int u,int c){
    color[u] = c;
    c == 1 ? cnt1++ : cnt2++;
    for(int i = h[u]; ~i; i = ne[i]){
        int j = e[i];
        if(color[j] == c) return false;
        if(!color[j] && !dfs(j,3-c)) return false;
    }
    return true;
}

int main(){
    scanf("%d%d",&n,&m);
    memset(h,-1,sizeof(h));
    for(int i = 1,u,v; i <= m; i++){
        scanf("%d%d",&u,&v);
        add_edge(u,v),add_edge(v,u);
    }
    for(int i = 1; i <= n; i++){
        if(!color[i]){
            cnt1 = cnt2 = 0;
            if(!dfs(i,1)){
                puts("0");
                return 0;
            }
            res1 += cnt1 * cnt2;
            res2 += (cnt1 + cnt2) * (n - cnt1 - cnt2);
        }
    }
    printf("%lld\n",res1+res2/2-(LL)m);
    return 0;
}

用上面的错误代码会 WA # 41,但是我和教练都觉得这么写没错,只会慢一点,请问错误代码错哪里了/kk

2022/12/18 14:17
加载中...