Meaning of the questions: given number N of the range of people, and then give a relationship of understanding between the number ab. Such a relationship is given m sets, then let you two separated
so that each person in each group do not know each other (not recognize indirect relationship), then if a packet, it will be recognized that two people into a room, rooms seek most in need
ideas: done before disjoint-set questions on the packets so first of all want to try and check the set (disjoint-set group is open twice arrays)
but think about self-analysis and check points set when in fact there is an indirect relationship, but also can not determine how to allocate the room
and then studied: bipartite graph matching
bipartite graph matching problem is given a map, as long as there is an edge between two points, then the two points can not be belong to a set of points must be on both sides.
(1) determining the bipartite graph: This question determines whether it is a bipartite graph:
Method: staining: We can start from a certain point, and then stained its connection to the dyed 1, 2 is connected Dianran If the
points connected thereto has been dyed 1 a, then this is certainly not a bipartite graph
(2): bipartite graph maximum matching: in a given figure we as possible twenty-two appreciated together i.e., we can every time
a fixed relationship between two people, and come up with map. The remaining matches will continue to find "augmenting path"
(augmenting paths: There are A, B collection, augmented Route A, a point B, leading to a point, then A, B, a point made this point leads ……process alternately)
Complete code:
#include<iostream> #include<vector> #include<cstring> using namespace std; const int maxn = 10010; int n,m;//顶点数 边数 vector<int> G[maxn]; int vis[maxn],match[maxn]; int color[maxn] ; //0 没染色 1 -1不同色 bool dfs(int u, int c){ color[u] = c; for(int i=0; i<G[u].size(); i++){ int V = G [U] [I]; // same color not IF (Color [V] == C) return to false ; // V no staining, staining recursively determines whether this established IF (Color [V] = = 0 && DFS (V, -C))! return to false ; } return to true ; } BOOL Solve () { for ( int I = . 1 ; I <= n-; I ++ ) { IF (Color [I] == 0 ) IF (! DFS (I, . 1 )) { return to false ; } } Return to true ; } // Hungarian algorithm: D FS augmenting path found BOOL the Find ( int U) { for ( int I = 0 ; I <G [U] .size (); I ++ ) { int X = I; IF (VIS [X] &&! G [U] [X]) { VIS [X] = . 1 ; IF (match [X] ||! the Find (match [X])) { match [X] = U; return true ; } } } return false; } int main(){ int t; cin>>t; while(t--){ cin >> n >> m; memset(color, 0, sizeof(color)); for(int i=0; i<maxn; i++) G[i].clear(); for(int i = 0; i < m; i++) { int s, t; cin >> s >>T; G [S] .push_back (T); G [T] .push_back (S); // if there is no need to FIG sentence } IF (Solve ()) { Memset (match, 0 , the sizeof (match) ); for ( int I = . 1 ; I <= n-; I ++ ) { Memset (VIS, 0 , the sizeof (VIS)); IF (the Find (I)) ANS ++ ; } COUT << ANS / 2 << endl; } the else cout << " No "<<endl; } return 0; }
bfs staining:
BOOL BFS ( int S) { Color [S] = . 1 ; Queue < int > Q; q.push (S); the while (! q.empty ()) { int U = q.front (); q.pop ( ); for ( int V = . 1 ; V <= n-; V ++ ) { // adjacent and no staining IF (G [U] [V] && Color [V] == 0 ) { q.push (V); color [V] = -color [U]; // dyed different colors } IF(G [U] [V] && Color [U] == Color [V]) { return to false ; } } } // All nodes and adjacent nodes are dyed different colors return to true ; }