提交 6a8182df 编写于 作者: qq_36480062's avatar qq_36480062

c

上级 3acefea0
......@@ -5,8 +5,42 @@ import java.util.Scanner;
public class 树的重心 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
int a, b;
for (int i = 0; i < n - 1; i++) {
a = sc.nextInt();
b = sc.nextInt();
add(a, b);
add(b, a);
}
dfs(1);
System.out.println(ans);
}
static int n, m;
private static int dfs(int u) {
vis[u] = 1;
int size = 0, sum = 0;
for (int i = he[u]; i != 0; i = ne[i]) {
int j = e[i];
if (vis[j] == 1) continue;
int s = dfs(j);
size = Math.max(size, s);
sum += s;//加上孩子节点的个数
}
size = Math.max(size, n - sum - 1);
ans = Math.min(ans, size);
return sum + 1;
}
static int n, cnt, ans=Integer.MAX_VALUE;
static int[] he = new int[100100];
static int[] ne = new int[200100];
static int[] e = new int[200100];
static int[] vis = new int[100100];
static void add(int a, int b) {
e[cnt] = b;
ne[cnt] = he[a];
he[a] = cnt++;
}
}
package 数学;
//https://blog.csdn.net/weixin_43237242/article/details/97388834
public class 欧拉函数 {
public static void main(String[] args) {
System.out.println(euler(6));
}
static long euler(long n) {
long ans = n;
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) {
ans = ans / i * (i - 1);
while (n % i == 0) {
n/=i;
}
}
}
if (n>1)ans=ans/n*(n-1);
return ans;
}
}
package 数学;
//线性筛质数
public class 线性筛 {
public static void main(String[] args) {
oldN(1234567);
}
static int cnt = 0;
static int[] prime = new int[100];
static boolean[] vis = new boolean[10000];
//让每个合数只被它的最小质因子筛选一次,以达到不重复的目的。
//太过牛逼只能背下来
static void ol(int n) {
for (int i = 2; i <= n; i++) {
if (!vis[i]) prime[cnt++] = i;
for (int j = 0; prime[j] <= n / i; j++) {
vis[prime[j] * i] = true;
if (i % prime[j] == 0) break;
}
}
}
static void oldN(int N) {
int n = N;
int r = 0;
while ((n / Math.log(n)) < N) {
r++;
n += 599;
}
System.out.println(r);
int cnt = 0;
prime = new int[n + 1];
vis = new boolean[n + 1];
for (int i = 2; i <= n; i++) {
if (!vis[i]) prime[cnt++] = i;
for (int j = 0; prime[j] <= n / i; j++) {
vis[prime[j] * i] = true;
if (i % prime[j] == 0) break;
}
}
System.out.println(prime[N - 1]);
}
}
......@@ -11,23 +11,89 @@ import java.util.Scanner;
* 状态定义:集合f[u,j]:所有从以u为根的子树中选,且总体积不超过j的选法
* 属性:max最大价值
* 集合划分:子树1,子树3,子树3
* 再根据体积划分子树:体积是0-m
* 再根据体积划分子树:体积是0-m 有m+1总可能
* 用一个数字表示一类方案
* 把每一颗子树看做物品组,分组背包问题
* 链式前向星建图
* 有 N 个物品和一个容量是 V
* 的背包。
* 物品之间具有依赖关系,且依赖关系组成一棵树的形状。如果选择一个物品,则必须选择它的父节点。
* 如下图所示:
* 如果选择物品5,则必须选择物品1和2。这是因为2是5的父节点,1是2的父节点。
* 每件物品的编号是 i
* ,体积是 vi,价值是 wi,依赖的父节点编号是 pi。物品的下标范围是 1…N
* 求解将哪些物品装入背包,可使物品总体积不超过背包容量,且总价值最大。
* 输出最大价值。
* 输入格式
* 第一行有两个整数 N,V
* ,用空格隔开,分别表示物品个数和背包容量。
* 接下来有 N
* 行数据,每行数据表示一个物品。
* 第 i 行有三个整数 vi,wi,pi,用空格隔开,分别表示物品的体积、价值和依赖的物品编号。
* 如果 pi=−1
* ,表示根节点。 数据保证所有物品构成一棵树。
* 输出格式
* 输出一个整数,表示最大价值。
* 数据范围
* 1≤N,V≤100
* 1≤vi,wi≤100
* 父节点编号范围:
* 内部结点:1≤pi≤N
* 根节点 pi=−1
* 输入样例
* 5 7
* 2 3 -1
* 2 2 1
* 3 5 1
* 4 7 2
* 3 6 2
* 输出样例:
* 11
*/
public class 有依赖的背包问题 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
v = sc.nextInt();
m = sc.nextInt();
int p, root = 0;
for (int i = 1; i <= n; i++) {
v[i] = sc.nextInt();
w[i] = sc.nextInt();
p = sc.nextInt();
if (p == -1) root = i;
else add(p, i);
}
dfs(root);
System.out.println(f[root][m]);
}
static void dfs(int u) {
for (int i = head[u]; i != 0; i = ne[i]) {
int son = e[i];
dfs(e[i]);
for (int j = m - v[u]; j >= 0; j--) {//枚举体积
for (int k = 0; k <= j; k++) {//枚举决策,分为以0~m的一些决策
f[u][j] = Math.max(f[u][j], f[u][j - k] + f[son][k]);
//以u为根节点,在剩余体积为0~m-v[u]的情况下,选子树
}
}
}
for (int i = m; i >= v[u]; i--) {
f[u][i] = f[u][i - v[u]] + w[u];
}//遍历完根节点的所有子树后
//能选的一定要选上01背包问题
for (int i = 0; i < v[u]; i++) {
f[u][i] = 0;
}//如果不能选赋值为0
}
static int[] v = new int[110], w = new int[110];
static int[][] f = new int[110][110];
static int N = 110;
static int[] head = new int[N], e = new int[N], ne = new int[N];
static int n, v, cnt = 1;
static int n, m, cnt = 1;
static void add(int a, int b) {
e[cnt] = b;
......
package 树形dp;
public class 树的直径 {
public static void main(String[] args) {
}
}
package 树形dp;
import java.util.Scanner;
/**
* https://blog.csdn.net/qq_30277239/article/details/100988651
* 树的重心是指树上一点,去掉后最大子树可以取得最小值的点。
* 去掉重心后,最大子树大小不超过n/2
* 下面简单描述下本题的解题过程。要想找到树的重心,需要知道去掉某节点后剩下连通块中节点的数量,对于某个节点u,以u为根节点的子树的节点总数为x,则其父节点(若存在)所在连通块节点的数目为n-x。要求以某节点为根节点子树的节点的个数,只需要递归的求以其孩子节点为根节点子树的总和即可。设int dfs(int u)这个函数能够实现该功能,则想要统计u所有子树节点之和,只需要int sum = 0;u的孩子节点比如有a,b,sum + dfs(a)+dfs(b) + 1即是u所在子树节点的总和了,同时,还可以求各个连通块节点的最大值,找到树的重心。
*/
public class 树的重心 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
int a, b;
for (int i = 1; i < n; i++) {
a = sc.nextInt();
b = sc.nextInt();
add(a, b);
add(b, a);
}
dfs(1);
// System.out.println(ans);
}
private static int dfs(int u) {
vis[u] = true;
int size = 0, sum = 0;
//
for (int i = he[u]; i != 0; i = ne[i]) {
int j = e[i];
if (vis[j]) continue;//不用遍历父节点
int s = dfs(j);
size = Math.max(size, s);
sum += s;
}
size = Math.max(size, n - sum - 1);
ans = Math.min(ans, size);
System.out.println(ans);
return sum + 1;//sum不+1就会恒等于0
}
static int ans = Integer.MAX_VALUE;
static boolean[] vis = new boolean[(int) (1e5 + 4)];
static int[] he = new int[(int) (1e5 + 4)];
static int[] ne = new int[(int) (2e5 + 4)];
static int[] e = new int[(int) (2e5 + 4)];
static int cnt = 1, n;
static void add(int a, int b) {
e[cnt] = b;
ne[cnt] = he[a];
he[a] = cnt++;
}
}
package 树形dp;
import java.util.Arrays;
import java.util.Scanner;
/**
* https://blog.csdn.net/qq_43326267/article/details/89789239
* 把每个节点看做根
* 9
* 1 2
* 2 3
* 2 4
* 4 5
* 1 6
* 6 7
* 7 8
* 7 9
*/
public class 树重心找节点 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
for (int i = 1; i < n; i++) {
add(sc.nextInt(), sc.nextInt());
}
dfs(1);
System.out.println(Arrays.toString(size));
System.out.println(Arrays.toString(maxpart));
}
private static void dfs(int u) {
vis[u] = true;
size[u] = 1;
for (int i = he[u]; i != 0; i = ne[i]) {
int j = e[i];
if (vis[j]) continue;
dfs(j);
size[u] += size[j];
maxpart[u] = Math.max(maxpart[u], size[j]);
}
maxpart[u] = Math.max(maxpart[u], n - size[u]);
//算出以u为根,u的父节点所在联通分量的节点数目
ans = Math.min(ans, maxpart[u]);
}
static int ans = Integer.MAX_VALUE;
static int[] size = new int[10010];
static int[] maxpart = new int[10010];
static int[] he = new int[10900];
static boolean[] vis = new boolean[10010];
static int[] ne = new int[10900 * 2];
static int[] e = new int[10900 * 2];
static int cnt = 1, n;
static void add(int a, int b) {
e[cnt] = b;
ne[cnt] = he[a];
he[a] = cnt++;
e[cnt] = a;
ne[cnt] = he[b];
he[b] = cnt++;
}
}
......@@ -7,7 +7,7 @@ public class 没有上司的舞会 {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
for (int i = 1; i <= n; i++) {
happy[i] = sc.nextInt();
f[i][1] = sc.nextInt();
}
int a, b;
for (int i = 0; i < n - 1; i++) {
......@@ -23,11 +23,11 @@ public class 没有上司的舞会 {
}
private static void dfs(int u) {
f[u][1] = happy[u];//选择了u就加上u的幸福指数
// f[u][1] = happy[u];//选择了u就加上u的幸福指数
for (int i = he[u]; i != 0; i = ne[i]) {
int j = e[i];
dfs(j);
f[u][1] += f[j][0];//不选子节点
f[u][1] += f[j][0];//选当前节点,但不选子节点
f[u][0] += Math.max(f[j][0], f[j][1]);
//不选当前节点,是选还是不选子节点
}
......
......@@ -50,7 +50,6 @@ import java.util.Scanner;
* 可以算出价值和体积
* 状态划分:不选第i种组件,f[i-1,j]
* 选第i种主件:f[i-1,j-v]+w 和第一个附件f[i-1,j-v]+w .... 或者不选第一个附件,选第二个附件...
*
*/
public class 金明的预算方案 {
static class node {
......
......@@ -2,7 +2,7 @@ package Math;
public class 欧拉线性筛最快的 {
public static void main(String[] args) {
eluer(12345);
eluer(12345798);
}
static int[] prime;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册