Bipartite graph: the vertices in the graph can be divided into two sets, and the elements in the set are independent.
Judgment: there are at least two vertices. If there are loops, the length must be even.
Dye method judgment: Dye x (- 1 or 1) from a point, traverse all its adjacent nodes, if not, dye - x, otherwise judge the point color, if x, the graph is not binary, exit; if - x, continue to traverse.
UVA - 10004 Bicoloring
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<algorithm> #include<string> #include<cstring> #include<map> #include<stack> #include<set> #include<queue> using namespace std; typedef long long ll; #define me(x) memset(x, -1, sizeof(x)) #define mem(x) memset(x, 0, sizeof(x)) const int MOD = 1e18; const int N = 2e5 + 5; struct node { int to, next, w; }e[N]; //Chain forward star map int head[N]; int vis[N]; int n, m, id, f; void ini() { id=0; f=0; me(head); mem(vis); } void add(int u, int v) { e[id].to = v; e[id].next = head[u]; head[u] = id++; } void bfs(int x) { queue<int> q; q.push(x); vis[x]=-1; while(q.size()) { x=q.front(); q.pop(); for(int i=head[x]; ~i; i=e[i].next) { if(!vis[e[i].to]) { q.push(e[i].to); vis[e[i].to]=-vis[x]; } else { if(vis[e[i].to] == vis[x]) {f=1;break;} } } if(f) break; } return ; } int main() { int i, j, k; int t; while(~scanf("%d", &n)) { if(!n) return 0; ini(); int u, v; scanf("%d", &m); for(i=0; i<m; i++) { scanf("%d%d", &u, &v); add(u,v);add(v,u); } bfs(0); if(f) printf("NOT BICOLORABLE.\n"); else printf("BICOLORABLE.\n"); } return 0; }
Matching: edge set, no common vertices for edges in the set
Max match: the maximum number of matches in a bipartite graph, that is, the maximum set of edges without common vertices.
Augmented path: an alternate path starting from the unmatched edge, along the unmatched edge matching edge unmatched edge matching edge unmatched edge
If it ends with an unmatched edge, the matching number is increased by 1 along the widening path
Hungarian algorithm idea: always find the augmented path, increase the matching number, and the matching number reaches the maximum when there is no augmented path
POJ - 1469 COURSES
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<string> #include<algorithm> #include<map> #include<queue> #include<stack> #include<list> #include<set> using namespace std; typedef int ll; typedef pair<ll,ll> P; typedef long double ld; #define mem(x) memset(x, 0, sizeof(x)) #define me(x) memset(x, -1, sizeof(x)) #define fo(i,n) for(i=0; i<n; i++) #define sc(x) scanf("%d", &x) #define sca(n,m) scanf("%d%d", &n, &m) #define pr(x) printf("%d\n", x) #define pri(x) printf("%d ", x) #define lowbit(x) x&-x const ll MOD = 1e9 + 7; const ll oo = 1e18; const ll N = 3e3 + 5; vector<ll> ve[N]; ll vis[N], cy[N]; ll dfs(ll u) { for(ll i=0; i<ve[u].size(); i++) { if(!vis[ve[u][i]]) { vis[ve[u][i]]=1; if(!cy[ve[u][i]] || dfs(cy[ve[u][i]])) //Looking for augmented Road { cy[ve[u][i]]=u; return 1; } } } return 0; } int main() { ll i, j, k; ll n, m, t; ll x; sc(t); while(t--) { sca(n,m); for(i=m+1; i<=m+n; i++) ve[i].clear(); mem(cy); for(i=m+1; i<=n+m; i++) { sc(k); for(j=0; j<k; j++) sc(x),ve[i].push_back(x); } ll ans=0; for(i=m+1; i<=n+m; i++) { for(j=1; j<=m; j++) vis[j]=0; if(dfs(i)) ans++; } if(ans==n) printf("YES\n"); else printf("NO\n"); } return 0; }