【hdu】5971 Wrestling Match
阿新 • • 發佈:2019-02-17
題目大意:
有n名球員,m場比賽。其中有x名好球員,y名壞球員。
好球員必定贏過壞球員,問能否把球員明確的區分為好、壞球員。
題解:
思路是二分圖染色,當然並查集也可以做。後續有空的話,會補上並查集做法。
利用比賽建圖。
先把好、壞球員的分別染色 color[i] = 1 和 color[i] = -1。
①然後依次深搜已染色球員,遇到相同顏色的就輸出 “NO”;
②若還有未染色球員,單個點輸出 “NO”,否則設為好球員 color[i] = 1進行深搜,重複①。
程式碼:
#include <iostream> #include <vector> #include <cstring> using namespace std; const int MAXN = 1e4+5; vector <int > G[MAXN]; int color[MAXN]; int n, m, x, y; int u, v; bool dfs(int v, int c){ color[v] = c; for(int i = 0; i < G[v].size(); ++i){ if(color[G[v][i]] == c) return false; if(color[G[v][i]] == 0 && !dfs(G[v][i], -c)) return false; } return true; } void solve(){ for(int i = 1; i <= n; ++i){ if(color[i] != 0){ if(!dfs(i, color[i])){ printf("NO\n"); return ; } } } for(int i = 1; i <= n; ++i){ if(color[i] == 0){ if(G[i].size()==0){ printf("NO\n"); return ; } if(!dfs(i, 1)){ printf("NO\n"); return ; } } } printf("YES\n"); } int main(){ while(scanf("%d %d %d %d", &n, &m, &x, &y) != EOF){ for(int i = 0; i <= MAXN; ++i){ G[i].clear(); } memset(color, 0, sizeof(color)); for(int i = 0; i < m; ++i){ scanf("%d %d", &u, &v); G[u].push_back(v); G[v].push_back(u); } for(int i = 0; i < x; ++i){ scanf("%d", &u); color[u] = 1; } for(int i = 0; i < y; ++i){ scanf("%d", &v); color[v] = -1; } solve(); } return 0; }