luogu_P1330 封锁阳光大学

https://www.luogu.org/problem/P1330

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

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

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


如果一个点选白,那么与他相连的点必须是黑

同一个联通快中,黑白可以互换

如果遍历到冲突了,就直接impossible

#include<iostream>
#include<cstdio>
#include<cstring>

#define ri register int
#define u int
#define NN 10005
#define MM 100005

namespace fast {
    inline u in() {
        u x(0);
        char s=getchar();
        while(s<'0'||s>'9') {
            s=getchar();
        }
        while(s>='0'&&s<='9') {
            x=(x<<1)+(x<<3)+s-'0';
            s=getchar();
        }
        return x;
    }
}

using fast::in;

namespace all {
    u cnt,ans,n,N,M,h[NN];
    struct node {
        u to,next;
    } a[MM<<1];
    inline void add(const u &x,const u &y) {
        a[++cnt].next=h[x],a[cnt].to=y,h[x]=cnt;
    }

    u vt[NN],co[NN];

    u dfs(const u &x,const u &k,const u &deep) {
        if(vt[x]) {
            if(co[x]^k) return 0;
            else return 1;
        }
        vt[x]=1,++n,co[x]=k,ans+=k;
        if(deep==N) return 1;
        for(ri i(h[x]); i; i=a[i].next) {
            u _y(a[i].to);
            if(!dfs(_y,k^1,deep+1)) return 0;
        }
        return 1;
    }

    inline void solve() {
        N=in(),M=in();
        for(ri i(1); i<=M; ++i) {
            u _a(in()),_b(in());
            add(_a,_b),add(_b,_a);
        }
        u as(0);
        for(ri i(1); i<=N; ++i) {
            ans=n=0;
            if(!vt[i]&&!dfs(i,1,1)){
                printf("Impossible");
                return;
            }
            as+=std::min(ans,n-ans);
        }
        printf("%d",as);
    }
}

int main() {
    //freopen("x.txt","r",stdin);
    all::solve();
}

猜你喜欢

转载自www.cnblogs.com/ling-zhi/p/11620819.html
今日推荐