2016 ICPC 大连 区域赛 A Wrestling Match (交叉染色法判断二分图)

题意:

给出n个点m条边,以及已知的好点和坏点。一个边连接的2个点一定是一好一坏,问是否有合法方案,使得每个点被确定好坏。

思路:

判断二分图。

先染已知的,再染未知的。

注意判掉没有出现的点。

注意有多个联通块。

  1    
  2    /* ***********************************************
  3    Author :111qqz
  4    Created Time :2017年10月26日 星期四 12时53分06秒
  5    File Name :A.cpp
  6    ************************************************ */
  7    
  8    #include <bits/stdc++.h>
  9    #define PB push_back
 10    #define fst first
 11    #define sec second
 12    #define lson l,m,rt<<1
 13    #define rson m+1,r,rt<<1|1
 14    #define ms(a,x) memset(a,x,sizeof(a))
 15    typedef long long LL;
 16    #define pi pair < int ,int >
 17    #define MP make_pair
 18    
 19    using namespace std;
 20    const double eps = 1E-8;
 21    const int dx4[4]={1,0,0,-1};
 22    const int dy4[4]={0,-1,1,0};
 23    const int inf = 0x3f3f3f3f;
 24    const int N=1005;
 25    const int M=1E4+7;
 26    int n,m,a,b;
 27    vector <int>edge[N];
 28    int col[N];
 29    set<int>se;
 30    bool dfs( int u,int x)
 31    {
 32        col[u] = x;
 33        int siz = edge[u].size();
 34        for ( int i = 0 ;i  < siz ; i++)
 35        {
 36        int v  = edge[u][i];
 37        if (col[v]==1-x) continue;
 38        if (col[v]==x) return false;
 39        if (!dfs(v,1-x)) return false;
 40        }
 41        return true;
 42    }
 43    void pr(int a[])
 44    {
 45        for ( int i = 1 ; i <= n ; i++) printf("%d%c",a[i],i==n?'\n':' ');
 46    }
 47    vector <int> A,B;
 48    bool appear[N];
 49    bool ran[N];
 50    int main()
 51    {
 52        #ifndef  ONLINE_JUDGE 
 53        freopen("./in.txt","r",stdin);
 54      #endif
 55        while (~scanf("%d %d %d %d",&n,&m,&a,&b))
 56        {
 57    
 58            bool die = false;
 59            ms(col,-1);
 60            A.clear();
 61            B.clear();
 62            ms(appear,false);
 63            ms(ran,false);
 64            for ( int i = 0 ; i <= n ; i++) edge[i].clear();
 65            for ( int i = 1 ; i <= m ; i++)
 66            {
 67            int u,v;
 68            scanf("%d %d",&u,&v);
 69            appear[u]=appear[v] = true;
 70            edge[u].PB(v);
 71            edge[v].PB(u);
 72            }
 73            for ( int i = 1 ; i <= a ; i++)
 74            {
 75            int x;
 76            scanf("%d",&x);
 77            appear[x] = true;
 78            A.PB(x);
 79            col[x] = 0 ;  //0 for good player
 80            }
 81            for ( int i =1 ; i <= b ; i++)
 82            {
 83            int x;
 84            scanf("%d",&x);
 85            appear[x] = true;
 86            B.PB(x);
 87            col[x] = 1;
 88            }
 89    
 90            for ( int i = 1 ; i <= n ; i++) if (!appear[i])
 91            {
 92            die = true;
 93            break;
 94            }
 95            if (die)
 96            {
 97            puts("NO");
 98            continue;
 99            }
100    
101            //可能有多个联通块
102            //
103            int siz = A.size();
104            for ( int i = 0 ; i < siz; i++)
105            {
106            int v = A[i];
107            if (!dfs(v,0))
108            {
109                die = true;
110                break;
111            }
112            }
113            if (die)
114            {
115            puts("NO");
116            continue;
117            }
118            
119            siz = B.size();
120            for ( int i = 0 ; i < siz; i++)
121            {
122            int v = B[i];
123            if (!dfs(v,1))
124            {
125                die = true;
126                break;
127            }
128            }
129            if (die)
130            {
131            puts("NO");
132            continue;
133            }
134    
135            for ( int i = 1 ; i <= n ; i++ )
136            {
137            if (col[i]==-1)
138            {
139                if (!dfs(i,0))
140                {
141                die = true;
142                break;
143                }
144            }
145            }
146    
147            if (die)
148            {
149            puts("NO");
150            continue;
151            }
152            puts("YES");
153        }
154    
155    
156      #ifndef ONLINE_JUDGE  
157      fclose(stdin);
158      #endif
159        return 0;
160    }
161