A - Wrestling Match (二分图染色)
题意略坑(没有说好的玩家一定能打过差的玩家啊啊~~)
典型的二分图染色问题,每个玩家看成一个点,把相互较量过的玩家之间连边,好的玩家染成黑色,差的玩家染成白色。先把能确定颜色的点都确定下来,然后剩下的点判断是不是二分图,推导过程中发现矛盾立即返回No。如果一个点没有和其他任何点相连且颜色不确定也返回No。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=1000+10; 5 int hd[N],ne,n,m,X,Y,col[N]; 6 struct E {int v,nxt;} e[20010]; 7 void addedge(int u,int v) {e[ne]= {v,hd[u]},hd[u]=ne++;} 8 bool dfs(int u,int c) { 9 if(~col[u])return col[u]==c; 10 col[u]=c; 11 for(int i=hd[u]; ~i; i=e[i].nxt) { 12 int v=e[i].v; 13 if(!dfs(v,col[u]^1))return 0; 14 } 15 return 1; 16 } 17 bool solve() { 18 for(int u=1; u<=n; ++u)if(~col[u]) { 19 for(int i=hd[u]; ~i; i=e[i].nxt) { 20 int v=e[i].v; 21 if(!dfs(v,col[u]^1))return 0; 22 } 23 } 24 for(int u=1; u<=n; ++u)if(!~col[u]) { 25 if(!~hd[u])return 0; 26 if(!dfs(u,0))return 0; 27 } 28 return 1; 29 } 30 31 int main() { 32 while(scanf("%d%d%d%d",&n,&m,&X,&Y)==4) { 33 memset(hd,-1,sizeof hd),ne=0; 34 memset(col,-1,sizeof col); 35 while(m--) { 36 int u,v; 37 scanf("%d%d",&u,&v); 38 addedge(u,v); 39 addedge(v,u); 40 } 41 while(X--) {int x; scanf("%d",&x); col[x]=1;} 42 while(Y--) {int x; scanf("%d",&x); col[x]=0;} 43 puts(solve()?"YES":"NO"); 44 } 45 return 0; 46 }