6-4 无向图的最大割问题
问题描述
给定一个无向图 G=(V,E),设 是 G 的顶点集。对任意(u,v)∈E,若有 u∈U 且v∈V-U,就称(u,v)为关于顶点集 U 的一条割边。顶点集 U 的所有割边构成图 G 的一个割。 G 的最大割是指 G 中所含边数最多的割。
对于给定的无向图 G,设计一个优先队列式分支限界法,计算 G 的最大割。
数据输入:
第 1 行有 2 个正整数 n 和 m,表示给定的图 G 有 n 个顶点和 m 条边,顶点编号为 1,2,…,n。接下来的 m 行中,每行有 2 个正整数 u,v,表示 图 G 的一条边(u,v)。
Java
package Chapter6FenZhiXianJieFa;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
public class WuXiangTuDeZuiDaGe {
private static class HeapNode implements Comparable{
int i,cut,e;
int[] x;
public int compareTo(Object o){
HeapNode heapNode = (HeapNode) o;
int result = Integer.compare(heapNode.cut+heapNode.e, cut+e);
return result;
}
}
private static int n,e,u,v;
private static int[][] a;
private static int[] p;
public static void main(String[] args){
Scanner input = new Scanner(System.in);
while (true){
n = input.nextInt();
e = input.nextInt();
a = new int[n+1][n+1];
p = new int[n+1];
for(int i=0; i<=n; i++)
for(int j=0; j<=n; j++)
a[i][j] = 0;
for(int i=1; i<=e; i++){
u = input.nextInt();
v = input.nextInt();
a[u][v] = 1;
a[v][u] = 1;
}
System.out.println(maxCut(a,p,n,e));
for(int i=1; i<=n; i++)
System.out.print(p[i]+" ");
}
}
private static class MCut{
int[][] a;
int[] bestx;
int n,e,bestn;
private void BBCut(){
Queue<HeapNode> H = new PriorityQueue<>(100000);
HeapNode E = new HeapNode();
E.x = new int[n+1];
E.cut=0; E.e=e; E.i=1;
for(int j=1; j<=n; j++) E.x[j]=0;
while (true){
if(E.i > n){
if(E.cut > bestn){
for(int j=1; j<=n; j++) bestx[j]=E.x[j];
bestn = E.cut;
}
}else {
addLiveNode(H,E,1);
if(E.cut+E.e > bestn) addLiveNode(H,E,0);
}
if(H.size() == 0) break;
E = H.poll();
}
}
private void addLiveNode(Queue<HeapNode> H, HeapNode E, int ch){
HeapNode N = new HeapNode();
int i = E.i;
N.x = new int[n+1];
for(int j=1; j<=n; j++) N.x[j]=E.x[j];
N.x[i]=ch; N.cut=E.cut; N.e=E.e;
if(ch > 0){
for(int j=1; j<=n; j++)
if(a[i][j] > 0){
if(N.x[j] == 0) {N.cut++; N.e--;}
else N.cut--;
}
}
N.i = i+1;
H.add(N);
}
}
private static int maxCut(int[][] a, int[] v, int n, int e){
MCut Y = new MCut();
Y.a=a; Y.n=n; Y.e=e; Y.bestn=0; Y.bestx=v;
Y.BBCut();
return Y.bestn;
}
}
Input & Output
7 18
1 4
1 5
1 6
1 7
2 3
2 4
2 5
2 6
2 7
3 4
3 5
3 6
3 7
4 5
4 6
5 6
5 7
6 7
12
1 1 1 0 0 0 0
10 33
1 3
1 6
1 8
1 10
2 3
2 4
2 6
2 7
2 9
2 10
3 4
3 5
3 7
3 8
3 9
3 10
4 5
4 6
4 7
4 8
4 10
5 6
5 7
5 9
6 7
6 8
6 9
6 10
7 9
7 10
8 9
8 10
9 10
22
1 1 0 0 1 0 1 1 0 0
Reference
王晓东《计算机算法设计与分析》(第3版)P226