hdu 5971 Wrestling Match

给一幅图,并且给出图里哪些是好点,哪些是坏点,问你这副图能不能被分成一个好点坏点图不矛盾。

我们先把给定了是好点或者坏点的点进行二分图染色,如果染出来是矛盾的就错误。

然后在把那些和已知点不在同一个联通块里的点随意指定初始颜色染色,染出来是矛盾的就错误。

 

 

 

 

 

#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define up rt,rt<<1,rt<<1|1
#define mem(x) memset(x,0,sizeof(x))
#define mem1(x) memset(x,-1,sizeof(x))
#define LMissher
using namespace std;
typedef long long ll;
typedef double db;
const int M = 1e4+7;
const double pi = acos(-1);
const int inf = 2147483647;
const int mod = 1e9+7;

int n,m,x,y;
int cnt,head[M],flag[M],vis[M];
struct edge
{
    int v,nex;
}e[M*20];
void init(){
    cnt=0;mem1(head);mem(flag);mem(vis);
}
void add(int u,int v){
    e[++cnt].v=v;e[cnt].nex=head[u];
    head[u]=cnt;
}
int dfs(int u,int c){
    // cout<<u<<" "<<c<<endl;
    vis[u]=1;
    flag[u]=c;
    for(int i=head[u];~i;i=e[i].nex){
        int v=e[i].v;
        if(flag[v]&&flag[v]!=c*-1) return 0;
        if(!vis[v]&&!dfs(v,c*-1)) return 0;
    }
    return 1;
}
int flg;
int main(){
    #ifdef LMissher
        freopen("1.in","r",stdin);
        freopen("1.out","w",stdout);
    #endif
    while(~scanf("%d%d%d%d",&n,&m,&x,&y)){
        init();
        flg=1;
        for(int i=1;i<=m;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            add(u,v);add(v,u);
        }
        int f;
        for(int i=1;i<=x;i++){
            scanf("%d",&f);flag[f]=1;
        }
        for(int i=1;i<=y;i++){
            scanf("%d",&f);flag[f]=-1;
        }
        for(int i=1;i<=n;i++){
            if(flag[i]&&!vis[i]) 
                if(!dfs(i,flag[i])) flg=0;
        }
        for(int i=1;i<=n;i++)
            if(!vis[i]){
                flag[i]=1;
                if(!dfs(i,flag[i])) flg=0;
            }
        if(flg) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}
View Code

 

posted @ 2018-09-19 16:31  LMissher  阅读(87)  评论(0)    收藏  举报