网页设计初学者公司网页设计模板班级优化大师免费下载电脑版
二分图判定算法
- 判断二分图
- dfs遍历
- bfs遍历
- 可能的二分法
- bfs遍历
- dfs遍历
二分图判定说白了就是遍历一遍图,一边遍历一边染色,看看能不能用两种颜色给所有节点染色,且相邻节点的颜色都不相同。
// 图遍历框架dfs
var traverse = function(graph, visited, v) {visited[v] = true;// 遍历节点 v 的所有相邻节点 neighborfor (var neighbor of graph.neighbors(v)) {if (!visited[neighbor]) {// 相邻节点 neighbor 没有被访问过// 那么应该给节点 neighbor 涂上和节点 v 不同的颜色traverse(graph, visited, neighbor);} else {// 相邻节点 neighbor 已经被访问过// 那么应该比较节点 neighbor 和节点 v 的颜色// 若相同,则此图不是二分图}}
}
判断二分图
链接
dfs遍历
class Solution {//用dfs遍历一遍图boolean res=true;boolean []visit;//保证每个节点只当一次start向四周染色boolean []col;public boolean isBipartite(int[][] graph) {int sz=graph.length;//节点的个数visit=new boolean[sz];col=new boolean[sz];for(int i=0;i<sz;i++){if(!visit[i]){dfs(graph,i);}}return res;}void dfs(int[][]graph,int start){if(res==false){return;}visit[start]=true;for(int neibor:graph[start]){if(!visit[neibor]){//染色col[neibor]=!col[start];dfs(graph,neibor);}else{//判断if(col[neibor]==col[start]){res=false;return;}}}}
}
bfs遍历
class Solution {public boolean isBipartite(int[][] graph) {int n=graph.length;boolean[]visit=new boolean[n];//记录进队列的节点,保证每个节点只进一次,进一次就相当于以这个节点为start了向四周染色了boolean[]col=new boolean[n];Queue<Integer> q=new LinkedList();for(int i=0;i<n;i++){if(visit[i]){continue;}//从i开始bfsq.add(i);visit[i]=true;while(!q.isEmpty()){int cur=q.poll();for(int neibor:graph[cur]){if(!visit[neibor]){//染色col[neibor]=!col[cur];q.add(neibor);visit[neibor]=true;}else{//检查if(col[neibor]==col[cur]){return false;}}}}}return true;}
}
可能的二分法
链接
bfs遍历
class Solution {//染过颜色就visit标记一下,然后进队列,进了队列就一定会出队列,出队列就会以它为中心向四周染色,visit[i]为真代表以i为中心向四周染色过public boolean possibleBipartition(int n, int[][] dislikes) {//先创建图,然后将图染色List<Integer>[]graph=new LinkedList[n+1];for(int i =1;i<=n;i++){graph[i]=new LinkedList();}for(int []e:dislikes){int a=e[0];int b=e[1];graph[a].add(b);graph[b].add(a);}boolean[]visit=new boolean[n+1];Queue<Integer> q=new LinkedList();boolean[]col=new boolean[n+1];for(int i=1;i<=n;i++){if(visit[i]){continue;}q.add(i);visit[i]=true;while(!q.isEmpty()){int cur=q.poll();for(int neibor:graph[cur]){if(!visit[neibor]){//染色col[neibor]=!col[cur];q.add(neibor);visit[neibor]=true;}else{//判断if(col[neibor]==col[cur]){return false;}}}}}return true;}
}
dfs遍历
class Solution {boolean[]col;boolean[]visit;//保证了每个节点都当过start一次,向四周染色boolean isBi=true;public boolean possibleBipartition(int n, int[][] dislikes) {//先创建图,然后将图染色List<Integer>[]graph=new LinkedList[n+1];for(int i =1;i<=n;i++){graph[i]=new LinkedList();}for(int []e:dislikes){int a=e[0];int b=e[1];graph[a].add(b);graph[b].add(a);}visit=new boolean[n+1];//visit[i]=true说明 以i为start向四周染色过col=new boolean[n+1];for(int i=1;i<=n;i++){if(!visit[i]){//没有以i为start过dfs(graph,i);}if(isBi==false){return false;}}return true;}//定义:从start开始遍历图,一边遍历一边涂色void dfs(List<Integer>[]graph,int start){if(!isBi){//已经知道不是二分图return;}visit[start]=true;for(int neibor:graph[start]){if(!visit[neibor]){//涂色col[neibor]=!col[start];dfs(graph,neibor);}else{if(col[neibor]==col[start]){isBi=false;return;}}}}
}