From 39e1cc60210d24056a13755e46c5ad8f901a16d0 Mon Sep 17 00:00:00 2001 From: Departuers <2644631299@qq.com> Date: Mon, 14 Sep 2020 13:45:30 +0800 Subject: [PATCH] c --- ...\350\276\223\345\260\217\347\214\253.java" | 2 +- ...\347\211\233\346\216\222\351\230\237.java" | 32 +++++++ .../\344\272\214\345\210\206\345\233\276.md" | 23 +++++ ...\345\233\276\345\210\244\345\256\232.java" | 77 +++++++++++++++- ...\346\212\274\347\275\252\347\212\257.java" | 87 ++++++++++++++++++- ...\344\272\214\345\210\206\345\233\276.java" | 3 +- ...\345\244\247\345\214\271\351\205\215.java" | 43 ++++++--- ...\346\260\217\347\255\233\346\263\225.java" | 2 +- ...\346\211\253\346\217\217\347\272\277.java" | 6 +- 9 files changed, 255 insertions(+), 20 deletions(-) create mode 100644 "ACWing/src/graph/\344\272\214\345\210\206\345\233\276/\344\272\214\345\210\206\345\233\276.md" diff --git "a/ACWing/src/DFS/\345\211\252\346\236\235/\350\277\220\350\276\223\345\260\217\347\214\253.java" "b/ACWing/src/DFS/\345\211\252\346\236\235/\350\277\220\350\276\223\345\260\217\347\214\253.java" index cc30b21..2efe00b 100644 --- "a/ACWing/src/DFS/\345\211\252\346\236\235/\350\277\220\350\276\223\345\260\217\347\214\253.java" +++ "b/ACWing/src/DFS/\345\211\252\346\236\235/\350\277\220\350\276\223\345\260\217\347\214\253.java" @@ -68,7 +68,7 @@ public class 运输小猫 { sum[i] += w[u]; dfs(u + 1, k); sum[i] -= w[u]; - } + } } //k的取值是0~k-1,所以下一次递归k就是下一辆车 sum[k] = w[u]; diff --git "a/ACWing/src/RMQ/\345\245\266\347\211\233\346\216\222\351\230\237.java" "b/ACWing/src/RMQ/\345\245\266\347\211\233\346\216\222\351\230\237.java" index a3790f5..3d4eb95 100644 --- "a/ACWing/src/RMQ/\345\245\266\347\211\233\346\216\222\351\230\237.java" +++ "b/ACWing/src/RMQ/\345\245\266\347\211\233\346\216\222\351\230\237.java" @@ -7,6 +7,38 @@ import static java.lang.System.in; /** * 题目:https://www.acwing.com/problem/content/description/1276/ + * 每天,农夫 John 的 N 头牛总是按同一序列排队。 + * 有一天,John 决定让一些牛玩一场飞盘比赛。 + * 他准备找一群在队列中位置连续的牛来进行比赛,但是为了避免水平悬殊,牛的身高不应该相差太大。 + * John 准备了 Q 个可能的牛的选择和所有牛的身高。 + * 他想知道每一组里面最高和最矮的牛的身高差别。 + * 输入格式 + * 第一行包含两个整数 N,Q。 + * 第二至第 N+1 行,第 i 行是第 i 头牛的身高 hi; + * 第 N+2 至第 N+Q+1 行,每行两个整数 A 和 B,表示从 A 到 B 的所有牛。 + * 牛的编号从 1 到 N。 + * 输出格式 + * 第一至第 Q 行,每行一个整数,表示对于询问的回答(即最高和最矮的牛的身高差)。 + * 数据范围 + * 1≤N≤5×104, + * 1≤Q≤1.8×105, + * 1≤hi≤106, + * 1≤A≤B≤N + * 输入样例: + * 6 3 + * 1 + * 7 + * 3 + * 4 + * 2 + * 5 + * 1 5 + * 4 6 + * 2 2 + * 输出样例: + * 6 + * 3 + * 0 * https://www.acwing.com/file_system/file/content/whole/index/content/568662/ */ public class 奶牛排队 { diff --git "a/ACWing/src/graph/\344\272\214\345\210\206\345\233\276/\344\272\214\345\210\206\345\233\276.md" "b/ACWing/src/graph/\344\272\214\345\210\206\345\233\276/\344\272\214\345\210\206\345\233\276.md" new file mode 100644 index 0000000..bf0142b --- /dev/null +++ "b/ACWing/src/graph/\344\272\214\345\210\206\345\233\276/\344\272\214\345\210\206\345\233\276.md" @@ -0,0 +1,23 @@ +#二分图 +```` +1.二分图,不存在奇数环等价于染色法不存在矛盾 + +2.匈牙利算法,匹配,最大匹配,匹配点,增广路径 + +3.最小点覆盖,最大独立集,最小路径点覆盖(最小路径重复点覆盖) + + +4.最大匹配数=最小点覆盖=总点数-最大独立集=总点数-最小路径覆盖 +上面四个等价 + +5最优匹配 +也就是给每条边一个权值,达到最大匹配使得所有权值最大 +使用km,最小费用流 + +6多重匹配一个点可以匹配多个点 +类似于多夫多妻,使用最大流 + +一个图是二分图等价图中不存在奇数环等价于染色不存在矛盾 + +假设不存在奇数环,染色法存在矛盾,无法染色 +假设两个点,都是白,他们之间存在...都是假设法... \ No newline at end of file diff --git "a/ACWing/src/graph/\344\272\214\345\210\206\345\233\276/\344\272\214\345\210\206\345\233\276\345\210\244\345\256\232.java" "b/ACWing/src/graph/\344\272\214\345\210\206\345\233\276/\344\272\214\345\210\206\345\233\276\345\210\244\345\256\232.java" index be85f3b..e72f76e 100644 --- "a/ACWing/src/graph/\344\272\214\345\210\206\345\233\276/\344\272\214\345\210\206\345\233\276\345\210\244\345\256\232.java" +++ "b/ACWing/src/graph/\344\272\214\345\210\206\345\233\276/\344\272\214\345\210\206\345\233\276\345\210\244\345\256\232.java" @@ -1,7 +1,82 @@ package graph.二分图; +import java.io.*; +import java.util.StringTokenizer; + +/** + * https://blog.csdn.net/qq_30277239/article/details/101471978 + * 给定一个n个点m条边的无向图,图中可能存在重边和自环。请你判断这个图是否是二分图。 + * 输入样例: + * 4 4 + * 1 3 + * 1 4 + * 2 3 + * 2 4 + * 输出样例: + * Yes + * + */ public class 二分图判定 { - public static void main(String[] args) { + public static void main(String[] args) throws IOException { + n = nextInt(); + m = nextInt(); + int a, b; + while (m-- != 0) { + a = nextInt(); + b = nextInt(); + add(a, b); + add(b, a); + } + boolean f = true; + for (int i = 1; i <= n; i++) { + if (color[i] == 0) {//有好几个连通块可能,我们要判定每一个能不能成为二分图 + if (!dfs(i, 1)) {//不能构成二分图就break + f = false; + break; + } + } + } + if (f) System.out.println("YES"); + else System.out.println("NO"); + } + + static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringTokenizer sk = new StringTokenizer(""); + + static String next() throws IOException { + while (!sk.hasMoreTokens()) { + sk = new StringTokenizer(br.readLine()); + } + return sk.nextToken(); + } + + static int nextInt() throws IOException { + return Integer.parseInt(next()); + } + + static int N = 100010, M = 201000, n, m, idx = 1; + static int[] h = new int[N]; + static int[] e = new int[M]; + static int[] ne = new int[M]; + static int[] color = new int[N]; + + static void add(int a, int b) { + e[idx] = b; + ne[idx] = h[a]; + h[a] = idx++; + } + + static boolean dfs(int u, int c) { + color[u] = c; + for (int i = h[u]; i != 0; i = ne[i]) { + int j = e[i]; + if (color[j] == 0) {//该点未被访问过 + if (!dfs(j, 3 - c)) return true; + } else if (color[j] == c) return false; + //u点和j点,也就是一条边的两边的颜色相同,我们就说他不是二分图 + } + return true; } } diff --git "a/ACWing/src/graph/\344\272\214\345\210\206\345\233\276/\345\205\263\346\212\274\347\275\252\347\212\257.java" "b/ACWing/src/graph/\344\272\214\345\210\206\345\233\276/\345\205\263\346\212\274\347\275\252\347\212\257.java" index 729f55e..4c93978 100644 --- "a/ACWing/src/graph/\344\272\214\345\210\206\345\233\276/\345\205\263\346\212\274\347\275\252\347\212\257.java" +++ "b/ACWing/src/graph/\344\272\214\345\210\206\345\233\276/\345\205\263\346\212\274\347\275\252\347\212\257.java" @@ -1,11 +1,92 @@ package graph.二分图; +import java.io.*; +import java.util.Arrays; +import java.util.StringTokenizer; + /** - * + * https://www.acwing.com/solution/content/3042/ + * 二分+染色判断 + * 使得二分图,求一边的罪犯仇恨值的最大值,最小 + * 答案0-10^9之间,看是否具有二分性质 + * check()怎么写至关重要 + * 也就是把答案区间分成两段,最优解把答案区间分成两段,一边具备这个性质,另一边不具备这个性质 + * 把大于mid边都删除,对应题目就是,把所有仇恨值大于某个值的两个罪犯,分到两个监狱,是不是二分图,可不可行 + * 如果可行那么最优解一定小于等于mid + * 对于最优解的右边一定也是满足性质,因为最优解释最小的那个点,选择大于最优解的值,去掉一些边,肯定还是二分图 + * 答案区间左边为不满足二分性质, */ public class 关押罪犯 { - public static void main(String[] args) { + public static void main(String[] args) throws IOException { + n = nextInt(); + m = nextInt(); + int a, b, c; + while (m-- != 0) { + a = nextInt(); + b = nextInt(); + c = nextInt(); + add(a, b, c); + add(b, a, c); + } + int l = 0, r = (int) 1e9; + while (l < r) { + int mid = l + r >> 1; + if (check(mid)) r = mid; + else l = mid + 1; + } + System.out.println(l); + } + + private static boolean check(int mid) { + Arrays.fill(color, 0);// + for (int i = 1; i <= n; i++) { + if (color[i] == 0) { + if (!dfs(i, 1, mid)) return false; + } + } + return true; + } + + static boolean dfs(int u, int colo, int mid) { + color[u] = colo; + for (int i = h[u]; i != 0; i = ne[i]) { + int j = e[i]; + if (w[i] <= mid) continue; + if (color[j] == 0) { + if (!dfs(j, 3 - colo, mid)) return false; + } else if (color[j] == colo) return false; + } + return true; + } + + static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringTokenizer sk = new StringTokenizer(""); + static String next() throws IOException { + while (!sk.hasMoreTokens()) { + sk = new StringTokenizer(br.readLine()); + } + return sk.nextToken(); } - static int n,m; + + static int nextInt() throws IOException { + return Integer.parseInt(next()); + } + + + static int n, m, N = 20010, M = 201000, idx = 1; + static int[] h = new int[N]; + static int[] e = new int[M]; + static int[] w = new int[M]; + static int[] ne = new int[M]; + static int[] color = new int[N]; + + static void add(int a, int b, int c) { + e[idx] = b; + w[idx] = c; + ne[idx] = h[a]; + h[a] = idx++; + } + } diff --git "a/ACWing/src/graph/\346\237\223\350\211\262\345\210\244\346\226\255\344\272\214\345\210\206\345\233\276.java" "b/ACWing/src/graph/\346\237\223\350\211\262\345\210\244\346\226\255\344\272\214\345\210\206\345\233\276.java" index 416d061..b4627a9 100644 --- "a/ACWing/src/graph/\346\237\223\350\211\262\345\210\244\346\226\255\344\272\214\345\210\206\345\233\276.java" +++ "b/ACWing/src/graph/\346\237\223\350\211\262\345\210\244\346\226\255\344\272\214\345\210\206\345\233\276.java" @@ -41,7 +41,6 @@ public class 染色判断二分图 { if (dfs(1, 0)) System.out.println("YES"); else System.out.println("NO"); } - System.out.println(Arrays.toString(vis)); } static boolean dfs(int u, int id) { @@ -49,7 +48,7 @@ public class 染色判断二分图 { for (int i = he[u]; i != 0; i = ne[i]) { int ed = e[i]; if (vis[ed] == -1) { - if (!dfs(ed, 1 - id)) return true; + if (!dfs(ed, 1 - id)) return false; } else if (vis[ed] == vis[u]) return false; } return true; diff --git "a/ACWing/src/graph/\346\264\233\350\260\267\344\272\214\345\210\206\345\233\276\346\234\200\345\244\247\345\214\271\351\205\215.java" "b/ACWing/src/graph/\346\264\233\350\260\267\344\272\214\345\210\206\345\233\276\346\234\200\345\244\247\345\214\271\351\205\215.java" index bf95a64..3027306 100644 --- "a/ACWing/src/graph/\346\264\233\350\260\267\344\272\214\345\210\206\345\233\276\346\234\200\345\244\247\345\214\271\351\205\215.java" +++ "b/ACWing/src/graph/\346\264\233\350\260\267\344\272\214\345\210\206\345\233\276\346\234\200\345\244\247\345\214\271\351\205\215.java" @@ -4,9 +4,27 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.StringTokenizer; -import java.util.TreeSet; /** + * P3386 【模板】二分图最大匹配 + * 给定一个二分图,其左部点的个数为 nn,右部点的个数为 mm,边数为 ee,求其最大匹配的边数。 + * 输入输出样例 + * 输入 + * 1 1 1 + * 1 1 + * 输出 + * 1 + * 输入 + * 4 2 7 + * 3 1 + * 1 2 + * 3 2 + * 1 1 + * 4 2 + * 4 1 + * 1 1 + * 输出 + * 2 * 洛谷ac,最快的 */ public class 洛谷二分图最大匹配 { @@ -18,7 +36,7 @@ public class 洛谷二分图最大匹配 { while (t-- != 0) { a = nextInt(); b = nextInt(); - g[a].add(b); + add(a, b); } for (int i = 1; i <= n; i++) { if (dfs(i, i)) ans++; @@ -29,7 +47,8 @@ public class 洛谷二分图最大匹配 { private static boolean dfs(int u, int tag) { if (st[u] == tag) return false; st[u] = tag; - for (Integer w : g[u]) { + for (int i = h[u]; i != 0; i = ne[i]) { + int w = e[i]; if (match[w] == 0 || dfs(match[w], tag)) { match[w] = u; return true; @@ -38,16 +57,20 @@ public class 洛谷二分图最大匹配 { return false; } - static int n, m, N = 1010, M = 50000, t = 0; - static TreeSet[] g = new TreeSet[N]; + static int n, m, N = 1010, M = 50000, t = 0, idx = 1; + static int[] h = new int[N]; + static int[] e = new int[M]; + static int[] ne = new int[M]; + + static void add(int a, int b) { + e[idx] = b; + ne[idx] = h[a]; + h[a] = idx++; + } + static int[] match = new int[N]; static int[] st = new int[N]; - static { - for (int i = 0; i < g.length; i++) { - g[i] = new TreeSet(); - } - } static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); static StringTokenizer stt = new StringTokenizer(""); diff --git "a/ACWing/src/\346\225\260\345\255\246/\345\237\203\346\260\217\347\255\233\346\263\225.java" "b/ACWing/src/\346\225\260\345\255\246/\345\237\203\346\260\217\347\255\233\346\263\225.java" index 510d9a0..3ba216a 100644 --- "a/ACWing/src/\346\225\260\345\255\246/\345\237\203\346\260\217\347\255\233\346\263\225.java" +++ "b/ACWing/src/\346\225\260\345\255\246/\345\237\203\346\260\217\347\255\233\346\263\225.java" @@ -6,7 +6,7 @@ package 数学; public class 埃氏筛法 { public static void main(String[] args) { long s = System.nanoTime(); - f(12345678); + e(12345678); long t = System.nanoTime(); System.out.println((t - s) / 1e8); s = System.nanoTime(); diff --git "a/ACWing/src/\347\272\277\346\256\265\346\240\221/\344\272\232\347\211\271\345\205\260\350\222\202\346\226\257\346\211\253\346\217\217\347\272\277.java" "b/ACWing/src/\347\272\277\346\256\265\346\240\221/\344\272\232\347\211\271\345\205\260\350\222\202\346\226\257\346\211\253\346\217\217\347\272\277.java" index 2b6f0e6..56f500d 100644 --- "a/ACWing/src/\347\272\277\346\256\265\346\240\221/\344\272\232\347\211\271\345\205\260\350\222\202\346\226\257\346\211\253\346\217\217\347\272\277.java" +++ "b/ACWing/src/\347\272\277\346\256\265\346\240\221/\344\272\232\347\211\271\345\205\260\350\222\202\346\226\257\346\211\253\346\217\217\347\272\277.java" @@ -3,7 +3,8 @@ package 线段树; import java.util.ArrayList; /** - * + * 积分思想 + * 分成几个小块扫描 */ public class 亚特兰蒂斯扫描线 { public static void main(String[] args) { @@ -22,7 +23,7 @@ public class 亚特兰蒂斯扫描线 { @Override public int compareTo(seg seg) { - return (int) (x*1000000-seg.x*1000000); + return (int) (x * 1000000 - seg.x * 1000000); } } @@ -33,6 +34,7 @@ public class 亚特兰蒂斯扫描线 { int l, r; int cnt = 0; double len; + } static node[] nodes = new node[N * 8]; -- GitLab