The phpisthebestageinttheworld (bipartite graph coloring + recursion) question of the hust school competition is to give an image and determine whether it is a bipartite graph. If yes, find the minimum difference between the two node sets in the bipartite graph.
If two people do not quarrel, they will join an edge to form a graph and take the reverse graph of the graph. There is an edge between the anti-image.
It means that the two cannot be in the same team. First, perform binary dyeing to see if the reverse graph can be converted into a binary graph.
If the image can be dyed into a bipartite graph, the number of colors in each bipartite graph is recorded. White/black in a Unicom component can be exchanged.
The following uses dp [I] [j] = 1 to indicate that the previous I Unicom component can form a team with a number of j.
Then, traverse the dp [num] [s] to find the team division method with the smallest difference, and output the answer. num is the number of connected components.
The code is as follows:
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
Using namespace std; # define LL long const int maxn = 100 + 5; const int INF = 1000000000; int color [maxn]; // vector
G [maxn]; int G [maxn] [maxn]; int one, two, num [maxn] [2], n; int d [maxn] [maxn]; bool bipartite (int u) {// determines whether the Unicom component of node u is a bipartite graph if (color [u] = 1) one ++; else two ++; for (int v = 1; v <= n; v ++) {if (G [u] [v] & u! = V) {if (color [u] = color [v]) return false; if (! Color [v]) {color [v] = 3-color [u]; if (! Bipartite (v) return false ;}} return true;} int main () {freopen ("input.txt", "r", stdin); int t; scanf ("% d", & t); while (t --) {memset (d, 0, sizeof (d); memset (color, 0, sizeof (color); int m; scanf ("% d", & n, & m); for (int I = 1; I <= n; I ++) for (int j = 1; j <= n; j ++) G [I] [j] = 1; for (int I = 0; I <m; I ++) {int u, v; scanf ("% d", & u, & v); if (G [u] [v]) G [u] [v] = G [v] [u] = 0;} int cnt = 0, tag = 1; for (int I = 1; I <= n; I ++) {if (! Color [I]) {one = 0, two = 0; color [I] = 1; if (! Bipartite (I) {tag = 0; break;} num [cnt] [0] = one; num [cnt] [1] = two; cnt ++ ;}} if (! Tag) printf ("No solution \ n"); else {for (int I = 0; I <cnt; I ++) {if (I = 0) d [I] [num [I] [0] = d [I] [num [I] [1] = 1; else for (int j = 0; j <= n; j ++) if (d [I-1] [j]) d [I] [j + num [I] [0] = d [I] [j + num [I] [1] = 1;} int ans = 1; for (int I = n/2; I --) if (d [cnt-1] [I]) {ans = I; break ;} printf ("% d \ n", ans) ;}} return 0 ;}
??