提交 39e1cc60 编写于 作者: qq_36480062's avatar qq_36480062

c

上级 916df8b0
......@@ -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];
......
......@@ -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 奶牛排队 {
......
#二分图
````
1.二分图,不存在奇数环等价于染色法不存在矛盾
2.匈牙利算法,匹配,最大匹配,匹配点,增广路径
3.最小点覆盖,最大独立集,最小路径点覆盖(最小路径重复点覆盖)
4.最大匹配数=最小点覆盖=总点数-最大独立集=总点数-最小路径覆盖
上面四个等价
5最优匹配
也就是给每条边一个权值,达到最大匹配使得所有权值最大
使用km,最小费用流
6多重匹配一个点可以匹配多个点
类似于多夫多妻,使用最大流
一个图是二分图等价图中不存在奇数环等价于染色不存在矛盾
假设不存在奇数环,染色法存在矛盾,无法染色
假设两个点,都是白,他们之间存在...都是假设法...
\ No newline at end of file
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;
}
}
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++;
}
}
......@@ -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;
......
......@@ -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<Integer>[] 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<Integer>();
}
}
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StringTokenizer stt = new StringTokenizer("");
......
......@@ -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();
......
......@@ -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];
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册