贪心算法之――黑白点的匹配(两种实现方法)

匿名 (未验证) 提交于 2019-12-02 21:52:03

一、题目

 

二、解题思路

http://5b0988e595225.cdn.sohucs.com/images/20171101/f1f45fe9ca37425ba200180be89624b2.gif

http://5b0988e595225.cdn.sohucs.com/images/20171101/a85c0716fcc847f1915dddfcfd019c01.gif

 

 

1、如何将黑白点化作图:

创建一个结构体

 

黑白点都看作顶点,只通过color进行区别

2、如何求对应邻接矩阵:

       对储存所有顶点的结构体数组做两次循环,若满足题目中黑点xy坐标大于白点,即将邻接矩阵该位置置为1。

3、具体流程演示:

 

 

三、代码(DFS BFS两种实现方法)

  1 public class MaxMatching {// 基于DFS   2    3     static int graph[][]; // 邻接表 默认全为0   4     static int n; // 节点数   5     static int visit[]; // 是否访问   6     static int matched[]; // 是否已经匹配,对应的匹配点   7     static vertex V[];//// 结构体数组储存所有黑白   8    9     public class vertex {// 顶点结构体  10         public int color;// 白:0 黑:1  11         public double Vx;  12         public double Vy;  13     }  14   15     public void Init() {  16         System.out.println("输入的黑白点总数为:");  17         Scanner sc = new Scanner(System.in);  18         n = sc.nextInt();  19         graph = new int[n][n]; // 邻接表 默认全为0  20         visit = new int[n]; // 是否访问  21         matched = new int[n]; // 是否已经匹配,对应的匹配点  22         V = new vertex[n];  23         InitGraph();// 初始邻接矩阵  24     }  25   26     private void InitGraph() {  27         Scanner sc = new Scanner(System.in);  28         for (int i = 0; i < n; i++) {// 输入黑白点  29             V[i] = new vertex();  30             System.out.println("please int color/x/y");  31             V[i].color = sc.nextInt();  32             V[i].Vx = sc.nextDouble();  33             V[i].Vy = sc.nextDouble();  34         }  35         for (int i = 0; i < n; i++) {  36             for (int j = 0; j < n; j++) {  37                 if (i != j && (V[i].color == 1) && (V[j].color == 0) && (V[i].Vx > V[j].Vx) && (V[i].Vy > V[j].Vy)) {  38                     graph[i][j] = 1;  39                 }  40             }  41         }  42     }  43   44     // 显示匹配结果  45     public void show() {  46         Arrays.fill(visit, 0);  47         for (int i = 0; i < n; i++) {  48             if (visit[i] == 0) {  49                 if (matched[i] != -1) {  50                     System.out.println("(" + V[i].Vx + "," + V[i].Vy + ")与" + "(" + V[matched[i]].Vx + ","  51                             + V[matched[i]].Vy + ")" + "匹配");  52                     visit[i] = 1;  53                     visit[matched[i]] = 1;  54                 }  55             }  56         }  57     }  58   59     /*  60      * dfs实现, params: x:起始的未匹配点 return: 1:找到增广路 0:未找到  61      */  62     public int dfs_solve(int x) {  63         // 找到一个和节点存在边的点,并且该点在本轮中没有被访问过  64         for (int i = 0; i < n; i++) {  65             if (graph[x][i] != 0 && visit[i] == 0) {  66                 visit[i] = 1; // 标记为匹配过  67                 // 按照交替路的模式找增广路,增广路相对于交替路的特性是就是,第一个节点和最后一个节点都是未匹配过的节点  68                 if (matched[i] == -1 || dfs_solve(matched[i]) == 1) { // 直接跳到matched[i]能够保证匹配边和未匹配边交替  69                     // 说明找到了一个未匹配节点,将所有匹配边变为未匹配边,将所有未匹配边变为匹配边,这样匹配边数会加1,这个交换过程通过回溯实现  70   71                     matched[x] = i;  72                     matched[i] = x;  73   74                     System.out  75                             .println("(" + V[x].Vx + "," + V[x].Vy + ") 与 " + "(" + V[i].Vx + "," + V[i].Vy + ")" + "匹配");  76                     return 1;  77                 }  78             }  79         }  80         return 0;  81     }  82   83     public void hungarian1() {  84         Arrays.fill(matched, -1);  85         int sum = 0;  86         for (int i = 0; i < n; i++) {  87             if (matched[i] == -1) {  88                 System.out.println("从 " + "(" + V[i].Vx + "," + V[i].Vy + ")" + " 开始匹配");  89                 Arrays.fill(visit, 0);// 重置浏览数组,用来浏览邻接矩阵当前列  90                 sum += dfs_solve(i);  91             }  92         }  93         System.out.println("\n"+"最后共有 " + sum + " 匹配项");  94         show();  95     }  96   97     public static void main(String[] args) {  98         MaxMatching mm = new MaxMatching();  99         mm.Init(); 100         mm.hungarian1(); 101     } 102 }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!