update
This commit is contained in:
parent
a87c80c00b
commit
3c0dc6f9a5
73
20240919/CSP常考算法模板/BFS.cpp
Normal file
73
20240919/CSP常考算法模板/BFS.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
#include<bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
struct node {
|
||||
int x, y, s;
|
||||
};
|
||||
|
||||
queue<node> q;
|
||||
int a[51][51];
|
||||
int dir[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; // 方向数组
|
||||
bool flag = false, book[51][51];
|
||||
int n, m, sx, sy, ex, ey;
|
||||
|
||||
void bfs(int sx,int sy)
|
||||
{
|
||||
q.push({sx, sy, 0}); // 星星之火, 可以燎原
|
||||
book[sx][sy] = true;
|
||||
|
||||
while(!q.empty() && !flag) {
|
||||
node temp = q.front();
|
||||
q.pop();
|
||||
for(int i=0; i<4;i++) {
|
||||
//算出新的位置坐标
|
||||
int nx = temp.x + dir[i][0];
|
||||
int ny = temp.y + dir[i][1];
|
||||
//判断新的位置是否越界
|
||||
if(nx<1 || nx > n || ny < 1 || ny > m)
|
||||
continue;
|
||||
// 如果新的位置是平地 并且 没有走过
|
||||
if(a[nx][ny]==0 && !book[nx][ny]) {
|
||||
q.push({nx, ny, temp.s+1});
|
||||
book[nx][ny] = true;
|
||||
// 新的位置是否为终点
|
||||
if(nx==ex && ny==ey) {
|
||||
flag = true;
|
||||
cout<<temp.s+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
cin>>n>>m;
|
||||
for(int i=1; i<=n; i++) {
|
||||
for(int j=1; j<=m; j++) {
|
||||
cin>>a[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
cin>>sx>>sy>>ex>>ey;
|
||||
|
||||
bfs(sx,sy);
|
||||
|
||||
if(!flag)
|
||||
cout<<"no";
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
5 4
|
||||
0 0 1 0
|
||||
0 0 0 0
|
||||
0 0 1 0
|
||||
0 1 0 0
|
||||
0 0 0 1
|
||||
1 1 4 3
|
||||
|
||||
输出
|
||||
7
|
||||
*/
|
61
20240919/CSP常考算法模板/DFS.cpp
Normal file
61
20240919/CSP常考算法模板/DFS.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
int n,m,p,q,minn=INT_MAX;
|
||||
int a[51][51];
|
||||
bool book[51][51];
|
||||
// 方向数组
|
||||
int dir[4][2]={ {0,1} , //向右走
|
||||
{1,0} , //向下走
|
||||
{0,-1}, //向左走
|
||||
{-1,0} } ;//向上走
|
||||
|
||||
void dfs(int x,int y,int step){
|
||||
// 判断是否到终点
|
||||
if(x==p && y==q){
|
||||
minn = min(minn, step);
|
||||
return;
|
||||
}
|
||||
|
||||
// 剪枝
|
||||
if(step>=minn) // 如果未到终点步数就已经达到或超过最小值,就返回。
|
||||
return;
|
||||
|
||||
// 枚举每一个方向
|
||||
for(int i=0; i<=3; i++){
|
||||
//计算下一个点的坐标
|
||||
int nx=x+dir[i][0];
|
||||
int ny=y+dir[i][1];
|
||||
|
||||
// 判断是否越界
|
||||
if(nx<1 || nx>n || ny<1 || ny>m)
|
||||
continue;
|
||||
|
||||
if(a[nx][ny]==0 && !book[nx][ny]){
|
||||
book[nx][ny]=true;
|
||||
dfs(nx,ny,step+1);
|
||||
book[nx][ny]=false; // 回溯
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main(){
|
||||
ios::sync_with_stdio(false);
|
||||
cin.tie(0);
|
||||
|
||||
int i ,j,startx,starty;
|
||||
cin>>n>>m;
|
||||
//读入迷宫
|
||||
for(i=1;i<=n;i++)
|
||||
for(j=1;j<=m;j++)
|
||||
cin>>a[i][j];
|
||||
|
||||
cin>>startx>>starty>>p>>q;
|
||||
|
||||
book[startx][starty]=true;
|
||||
dfs(startx,starty,0);
|
||||
|
||||
cout<<minn<<endl;
|
||||
return 0;
|
||||
}
|
84
20240919/CSP常考算法模板/LCA_倍增.cpp
Normal file
84
20240919/CSP常考算法模板/LCA_倍增.cpp
Normal file
@ -0,0 +1,84 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
const int N = 500001;
|
||||
|
||||
struct Edge {
|
||||
int to;
|
||||
int nxt;
|
||||
} e[2*N];
|
||||
|
||||
int n,m,s;
|
||||
int depth[N], Log[N];
|
||||
int dbl[N][20]; //倍增数组
|
||||
int head[N], tot;
|
||||
|
||||
void addEdge(int x,int y) {
|
||||
e[++tot].to=y;
|
||||
e[tot].nxt=head[x];
|
||||
head[x]=tot;
|
||||
}
|
||||
|
||||
void dfs(int cur, int fa) {
|
||||
depth[cur]=depth[fa]+1;
|
||||
dbl[cur][0]=fa;
|
||||
for(int i=1; (1<<i) < depth[cur]; i++) {
|
||||
int mid = dbl[cur][i-1];
|
||||
dbl[cur][i]=dbl[mid][i-1]; // 计算倍增数组
|
||||
}
|
||||
|
||||
for(int i=head[cur]; i>0; i=e[i].nxt) {
|
||||
if(e[i].to != fa) // 遍历子节点
|
||||
dfs(e[i].to, cur);
|
||||
}
|
||||
}
|
||||
|
||||
int lca(int x,int y) {
|
||||
// 把两个点升至同一高度,再一起跳
|
||||
if(depth[x]<depth[y]) { // 规定x更深
|
||||
swap(x,y);
|
||||
}
|
||||
|
||||
while(depth[x]>depth[y]) {
|
||||
x=dbl[x][Log[depth[x]-depth[y]]];
|
||||
}
|
||||
|
||||
if(x==y)
|
||||
return x;
|
||||
|
||||
// 两个点同时往上跳,跳到LCA的下一层为止
|
||||
for(int i=Log[depth[x]]; i>=0; i--)
|
||||
if(dbl[x][i] != dbl[y][i]) {
|
||||
x=dbl[x][i];
|
||||
y=dbl[y][i];
|
||||
}
|
||||
|
||||
return dbl[x][0];
|
||||
}
|
||||
|
||||
/*
|
||||
倍增算法时间复杂度是O(nlogn)
|
||||
*/
|
||||
int main() {
|
||||
scanf("%d%d%d",&n,&m,&s);
|
||||
for(int i=1; i<=n-1; i++) {
|
||||
int x,y;
|
||||
scanf("%d%d",&x,&y);
|
||||
addEdge(x,y);
|
||||
addEdge(y,x);
|
||||
}
|
||||
dfs(s,0); // 建树
|
||||
|
||||
// 预处理,常数优化
|
||||
for(int i=2; i<=n; i++) {
|
||||
Log[i]=Log[i>>1] + 1;
|
||||
}
|
||||
|
||||
for(int i=1; i<=m; i++) {
|
||||
int x, y;
|
||||
scanf("%d%d", &x, &y);
|
||||
printf("%d\n", lca(x, y));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
87
20240919/CSP常考算法模板/P3379【模板】LCA_倍增 -邻接表.cpp
Normal file
87
20240919/CSP常考算法模板/P3379【模板】LCA_倍增 -邻接表.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
const int N = 500001;
|
||||
|
||||
int n,m,s;
|
||||
int depth[N], Log[N];
|
||||
int dbl[N][20]; //倍增数组
|
||||
int tot;
|
||||
vector<int> graph[N];
|
||||
|
||||
void dfs(int cur, int fa) {
|
||||
//todo
|
||||
depth[cur]=depth[fa]+1;
|
||||
dbl[cur][0]=fa;
|
||||
for(int i=1;(1<<i)<depth[cur];i++)
|
||||
{
|
||||
int mid=dbl[cur][i-1];
|
||||
dbl[cur][i]=dbl[mid][i-1];
|
||||
}
|
||||
for(int v:graph[cur])
|
||||
{
|
||||
if(v!=fa)
|
||||
{
|
||||
dfs(v,cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int lca(int x,int y) {
|
||||
// 把两个点升至同一高度,再一起跳
|
||||
// TODO
|
||||
if(depth[x]<depth[y])
|
||||
{
|
||||
swap(x,y);
|
||||
}
|
||||
while(depth[x]>depth[y])
|
||||
{
|
||||
int h=Log[depth[x]-depth[y]];
|
||||
x=dbl[x][h];
|
||||
}
|
||||
|
||||
if(x==y)
|
||||
return x;
|
||||
|
||||
// 两个点同时往上跳,跳到LCA的下一层为止
|
||||
// TODO
|
||||
int h=Log[depth[x]];
|
||||
for(int i=h;i>=0;i--)
|
||||
{
|
||||
if(dbl[x][i]!=dbl[y][i])
|
||||
{
|
||||
x=dbl[x][i];
|
||||
y=dbl[y][i];
|
||||
}
|
||||
}
|
||||
return dbl[x][0];
|
||||
}
|
||||
|
||||
/*
|
||||
倍增算法时间复杂度是O(nlogn)
|
||||
*/
|
||||
int main() {
|
||||
scanf("%d%d%d",&n,&m,&s);
|
||||
for(int i=1; i<=n-1; i++) {
|
||||
int x,y;
|
||||
scanf("%d%d",&x,&y);
|
||||
//todo
|
||||
graph[x].push_back(y);
|
||||
graph[y].push_back(x);
|
||||
}
|
||||
dfs(s,0); // 建树
|
||||
|
||||
// 预处理,常数优化
|
||||
for(int i=2; i<=n; i++) {
|
||||
//todo
|
||||
Log[i]=Log[i/2]+1;
|
||||
}
|
||||
|
||||
for(int i=1; i<=m; i++) {
|
||||
int x,y;
|
||||
scanf("%d%d",&x,&y);
|
||||
printf("%d\n",lca(x,y));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
53
20240919/CSP常考算法模板/P3379【模板】LCA_倍增 -邻接表_todo.cpp
Normal file
53
20240919/CSP常考算法模板/P3379【模板】LCA_倍增 -邻接表_todo.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
const int N = 500001;
|
||||
|
||||
int n,m,s;
|
||||
int depth[N], Log[N];
|
||||
int dbl[N][20]; //倍增数组
|
||||
int tot;
|
||||
vector<int> graph[N];
|
||||
|
||||
void dfs(int cur, int fa) {
|
||||
//todo
|
||||
}
|
||||
|
||||
int lca(int x,int y) {
|
||||
// 把两个点升至同一高度,再一起跳
|
||||
// TODO
|
||||
|
||||
if(x==y)
|
||||
return x;
|
||||
|
||||
// 两个点同时往上跳,跳到LCA的下一层为止
|
||||
// TODO
|
||||
|
||||
return dbl[x][0];
|
||||
}
|
||||
|
||||
/*
|
||||
倍增算法时间复杂度是O(nlogn)
|
||||
*/
|
||||
int main() {
|
||||
scanf("%d%d%d",&n,&m,&s);
|
||||
for(int i=1; i<=n-1; i++) {
|
||||
int x,y;
|
||||
scanf("%d%d",&x,&y);
|
||||
//todo
|
||||
}
|
||||
dfs(s,0); // 建树
|
||||
|
||||
// 预处理,常数优化
|
||||
for(int i=2; i<=n; i++) {
|
||||
//todo
|
||||
}
|
||||
|
||||
for(int i=1; i<=m; i++) {
|
||||
int x,y;
|
||||
scanf("%d%d",&x,&y);
|
||||
printf("%d\n",lca(x,y));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
39
20240919/CSP常考算法模板/RMQ.cpp
Normal file
39
20240919/CSP常考算法模板/RMQ.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
const int N = 1e6 + 5;
|
||||
const int LOGN = 20;
|
||||
|
||||
int Log[N] = {-1}, f[N][LOGN + 1], a[N]; // f[i][j] 存储[i, i+2^j-1]之间的最值
|
||||
int n, m;
|
||||
|
||||
int main() {
|
||||
ios::sync_with_stdio(false);
|
||||
cin.tie(0), cout.tie(0);
|
||||
|
||||
cin>>n>>m;
|
||||
for(int i=1; i<=n; ++i) {
|
||||
cin>>a[i];
|
||||
}
|
||||
|
||||
for(int i=1; i<=n; ++i) {
|
||||
f[i][0]=a[i];
|
||||
Log[i]=Log[i>>1] + 1; // 预处理出长度为1~n的log值
|
||||
}
|
||||
|
||||
for(int j=1; j<=LOGN; j++) { // 注意是j
|
||||
for(int i=1; i+(1<<j)-1<=n; i++) { // 注意要加括号(1<<j)
|
||||
f[i][j]=max(f[i][j-1], f[i+(1<<(j-1))][j-1]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 1; i <= m; i++) {
|
||||
int x, y;
|
||||
cin>>x>>y;//3 8
|
||||
int s=Log[y-x+1];
|
||||
cout<<max(f[x][s], f[y-(1<<s)+1][s])<<endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
38
20240919/CSP常考算法模板/二分查找_加速查询.cpp
Normal file
38
20240919/CSP常考算法模板/二分查找_加速查询.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
int a[11]={5, 13, 19, 21, 37, 56, 64, 75, 80, 88, 92};
|
||||
|
||||
int main()
|
||||
{
|
||||
int x;
|
||||
cin>>x;
|
||||
int l=0,r=10;
|
||||
int ans;
|
||||
while(l<=r)
|
||||
{
|
||||
int mid=(l+r)/2;
|
||||
if(x==a[mid])
|
||||
{
|
||||
cout<<mid;
|
||||
return 0;
|
||||
}
|
||||
if(x<a[mid])
|
||||
{
|
||||
r=mid-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ans=mid;
|
||||
l=mid+1;
|
||||
}
|
||||
}
|
||||
cout<<"Not found!";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//5
|
||||
//1 -2 3 1 -4
|
||||
|
||||
|
47
20240919/CSP常考算法模板/二分查找_满足条件的最值问题.cpp
Normal file
47
20240919/CSP常考算法模板/二分查找_满足条件的最值问题.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
int n, tmax;
|
||||
int t[10001];
|
||||
|
||||
bool check(int k) {
|
||||
priority_queue<int, vector<int>, greater<int> > pq;
|
||||
for(int i=0; i<k; i++) {
|
||||
pq.push(t[i]);
|
||||
}
|
||||
for(int i=k; i<n; i++) {
|
||||
int a = pq.top();
|
||||
pq.pop();
|
||||
pq.push(a + t[i]);
|
||||
}
|
||||
while(pq.size() > 1) {
|
||||
pq.pop();
|
||||
}
|
||||
return tmax >= pq.top();
|
||||
}
|
||||
|
||||
int main() {
|
||||
// freopen("cowdance.in","r",stdin);
|
||||
// freopen("cowdance.out","w",stdout);
|
||||
//
|
||||
ios::sync_with_stdio(false);
|
||||
cin.tie(0);
|
||||
|
||||
cin>>n>>tmax;
|
||||
for(int i=0; i<n; i++) {
|
||||
cin>>t[i];
|
||||
}
|
||||
int left = 1, right = n, ans = n;
|
||||
while(left<=right) {
|
||||
int mid = (left+right)/2;
|
||||
if(check(mid)) {
|
||||
ans = mid;
|
||||
right = mid - 1;
|
||||
} else {
|
||||
left = mid + 1;
|
||||
}
|
||||
}
|
||||
cout<<ans<<endl;
|
||||
|
||||
return 0;
|
||||
}
|
29
20240919/CSP常考算法模板/二维前缀和.cpp
Normal file
29
20240919/CSP常考算法模板/二维前缀和.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
int x[4][5] = {{},{0,3,2,1,5},{0,7,1,2,8},{0,1,3,4,6}};
|
||||
int prefix[4][5];
|
||||
int sum[4][5];
|
||||
int main()
|
||||
{
|
||||
|
||||
for(int i=1;i<=3;i++)
|
||||
{
|
||||
for(int j=1;j<=4;j++)
|
||||
{
|
||||
//todo
|
||||
prefix[i][j]=prfix[i-1][j]+prefix[i][j-1]-prefix[i-1][j-1]+x[i][j];
|
||||
}
|
||||
}
|
||||
for(int i=1;i<=3;i++)
|
||||
{
|
||||
for(int j=1;j<=4;j++)
|
||||
{
|
||||
cout<<prefix[i][j]<<" ";
|
||||
}
|
||||
cout<<endl;
|
||||
}
|
||||
int a=1,b=1,A=3,B=4;
|
||||
int ans=prefix[A][B]-prefix[A][b-1]-prefix[a-1][B]+prefix[a-1][b-1];
|
||||
cout<<ans;
|
||||
return 0;
|
||||
}
|
39
20240919/CSP常考算法模板/全排列.cpp
Normal file
39
20240919/CSP常考算法模板/全排列.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
#include<bits/stdc++.h>
|
||||
using namespace std;
|
||||
bool book[10]; //false±íʾûÓùý
|
||||
int a[10];
|
||||
|
||||
void print()
|
||||
{
|
||||
for(int i=1;i<=4;i++)
|
||||
{
|
||||
cout<<a[i]<<" ";
|
||||
}
|
||||
cout<<endl;
|
||||
}
|
||||
|
||||
void dfs(int step)
|
||||
{
|
||||
if(step==5)
|
||||
{
|
||||
print();
|
||||
return ;
|
||||
}
|
||||
for(int i=1;i<=4;i++)
|
||||
{
|
||||
if(!book[i])
|
||||
{
|
||||
book[i]=true;
|
||||
a[step]=i;
|
||||
dfs(step+1);
|
||||
book[i]=false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
dfs(1);
|
||||
|
||||
return 0;
|
||||
}
|
37
20240919/CSP常考算法模板/前缀和.cpp
Normal file
37
20240919/CSP常考算法模板/前缀和.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
int n, a[1001], prefix[1001];
|
||||
|
||||
int main()
|
||||
{
|
||||
freopen("bcount.in","r",stdin);
|
||||
freopen("bcount.out","w",stdout);
|
||||
cin>>n;
|
||||
|
||||
for(int i=1; i<=n; i++)
|
||||
{
|
||||
cin>>a[i];
|
||||
//todo
|
||||
prefix[i]=prefix[i-1]+a[i];
|
||||
}
|
||||
|
||||
int ans = INT_MIN;
|
||||
for(int i=1;i<=n;i++) //begin location
|
||||
{
|
||||
for(int j=i;j<=n;j++) //end location
|
||||
{
|
||||
ans=max(ans,prefix[j]-prefix[i-1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cout<<ans<<endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//5
|
||||
//1 -2 3 1 -4
|
||||
|
||||
|
55
20240919/CSP常考算法模板/区间dp/区间dp_合并石子.cpp
Normal file
55
20240919/CSP常考算法模板/区间dp/区间dp_合并石子.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
int a[101];
|
||||
int sum[101]; // prefix sum
|
||||
int f[101][101];
|
||||
/*
|
||||
区间动态规划解题步骤:
|
||||
1.根据问题推测dp[i][j]的含义
|
||||
问题是:把第1堆到第n堆石子合成一堆,最小的得分
|
||||
dp[i][j]的含义:把第i堆到第j堆石子合成一堆,最小的得分
|
||||
2.根据规则推出dp[i][j]的状态转移公式
|
||||
在i-j之间选一个中间值k,
|
||||
dp[i][j]=dp[i][k]+dp[k+1][j]+(sum[j]-s[i-1]);
|
||||
3.边界问题(比如设定dp[0][0],dp[0][j],dp[i][0],dp[i][j],dp[i][i]初始值)
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
input
|
||||
7
|
||||
13
|
||||
7
|
||||
8
|
||||
16
|
||||
21
|
||||
4
|
||||
18
|
||||
|
||||
output
|
||||
239
|
||||
*/
|
||||
int main() {
|
||||
ios::sync_with_stdio(false);
|
||||
cin.tie(0);
|
||||
int n;
|
||||
cin>>n;
|
||||
|
||||
for(int i=1; i<=n; i++) {
|
||||
cin>>a[i];
|
||||
sum[i] = sum[i-1] + a[i];
|
||||
}
|
||||
|
||||
for(int i=n-1; i>=1; i--) { //一定要逆序
|
||||
for(int j=i+1; j<=n; j++) {
|
||||
f[i][j] = INT_MAX;
|
||||
for(int k=i; k<=j-1; k++) {
|
||||
f[i][j] = min(f[i][j], f[i][k]+f[k+1][j] + sum[j]-sum[i-1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cout<<f[1][n]<<endl;
|
||||
return 0;
|
||||
}
|
38
20240919/CSP常考算法模板/图的存储_vector.cpp
Normal file
38
20240919/CSP常考算法模板/图的存储_vector.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
vector<int> graph[101];
|
||||
|
||||
int main()
|
||||
{
|
||||
int n,m,x,y;
|
||||
cin>>n>>m;
|
||||
for(int i=1;i<=m;i++)
|
||||
{
|
||||
cin>>x>>y;
|
||||
//todo
|
||||
graph[x].push_back(y);
|
||||
graph[y].push_back(x);
|
||||
}
|
||||
for(int i=1;i<=n;i++)
|
||||
{
|
||||
//todo
|
||||
// for(int j=0;j<graph[i].size();j++)
|
||||
// {
|
||||
// cout<<graph[i][j]<<" ";
|
||||
// }
|
||||
for(int j:graph[i])
|
||||
{
|
||||
cout<<j<<" ";
|
||||
}
|
||||
cout<<endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
5 5
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 1
|
||||
*/
|
55
20240919/CSP常考算法模板/并查集.cpp
Normal file
55
20240919/CSP常考算法模板/并查集.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
int n,m,p;
|
||||
int f[5001];
|
||||
|
||||
int find(int x)
|
||||
{
|
||||
if(x==f[x])
|
||||
{
|
||||
return x;
|
||||
}
|
||||
return f[x]=find(f[x]);
|
||||
}
|
||||
|
||||
void merge(int u, int v)
|
||||
{
|
||||
int fu=find(u);
|
||||
int fv=find(v);
|
||||
if(fu!=fv)
|
||||
{
|
||||
f[fu]=fv;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
cin>>n>>m>>p;
|
||||
for(int i=1;i<=n;i++)
|
||||
{
|
||||
f[i]=i;
|
||||
}
|
||||
for(int i=1;i<=m;i++)
|
||||
{
|
||||
int a,b;
|
||||
cin>>a>>b;
|
||||
merge(a,b);
|
||||
}
|
||||
|
||||
for(int i=1;i<=p;i++)
|
||||
{
|
||||
int a,b;
|
||||
cin>>a>>b;
|
||||
if(find(a)==find(b))
|
||||
{
|
||||
cout<<"Yes"<<endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout<<"No"<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
55
20240919/CSP常考算法模板/并查集样例程序.cpp
Normal file
55
20240919/CSP常考算法模板/并查集样例程序.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
int n,m,p;
|
||||
int f[5001];
|
||||
|
||||
int find(int x)
|
||||
{
|
||||
if(x==f[x])
|
||||
{
|
||||
return x;
|
||||
}
|
||||
return find(f[x]);
|
||||
}
|
||||
|
||||
void merge(int u, int v)
|
||||
{
|
||||
int fu=find(u);
|
||||
int fv=find(v);
|
||||
if(fu!=fv)
|
||||
{
|
||||
f[fu]=fv;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
cin>>n>>m>>p;
|
||||
for(int i=1;i<=n;i++)
|
||||
{
|
||||
f[i]=i;
|
||||
}
|
||||
for(int i=1;i<=m;i++)
|
||||
{
|
||||
int a,b;
|
||||
cin>>a>>b;
|
||||
merge(a,b);
|
||||
}
|
||||
|
||||
for(int i=1;i<=p;i++)
|
||||
{
|
||||
int a,b;
|
||||
cin>>a>>b;
|
||||
if(find(a)==find(b))
|
||||
{
|
||||
cout<<"Yes"<<endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout<<"No"<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
26
20240919/CSP常考算法模板/快速幂.cpp
Normal file
26
20240919/CSP常考算法模板/快速幂.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
int b, p, k;
|
||||
|
||||
/*
|
||||
原理:a*b%k=(a%k)*(b%k)%k
|
||||
对于任何一个自然数:p=2*(p/2)+p%2
|
||||
*/
|
||||
int f(int p) {
|
||||
if(p==0) // b^0%k
|
||||
return 1%k;
|
||||
int t=f(p/2)%k;
|
||||
t=(t*t)%k; // b^p%k=(b^(p/2))^2%k
|
||||
if(p%2==1)
|
||||
t=(t*b)%k; // 如果p为奇数,则b^p%k=((b^(p/2))^2)*b%k
|
||||
return t;
|
||||
}
|
||||
|
||||
int main(){
|
||||
cin>>b>>p>>k;
|
||||
int tmpb=b;
|
||||
b%=k;
|
||||
printf("%d^%d mod %d=%d", tmpb, p, k, f(p));
|
||||
return 0;
|
||||
}
|
36
20240919/CSP常考算法模板/拓扑排序.cpp
Normal file
36
20240919/CSP常考算法模板/拓扑排序.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
#include<bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int MAX_A=100005;
|
||||
int to[MAX_A];
|
||||
int inDegree[MAX_A];
|
||||
|
||||
int main() {
|
||||
int n;
|
||||
cin>>n;
|
||||
for (int i=1; i<=n; i++) {
|
||||
cin>>to[i];
|
||||
inDegree[to[i]]++;
|
||||
}
|
||||
queue<int> q;
|
||||
int cnt = 0;
|
||||
for (int i=1; i<=n; i++) {
|
||||
if (inDegree[i]==0) {
|
||||
q.push(i);
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
while (q.size()>0) {
|
||||
int t=q.front();
|
||||
q.pop();
|
||||
int v = to[t];
|
||||
inDegree[v]--;
|
||||
if (inDegree[v]==0) {
|
||||
q.push(v);
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
cout<<n-cnt<<endl;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
62
20240919/CSP常考算法模板/最小生成树/最小生成树_Prim(稠密图)..cpp
Normal file
62
20240919/CSP常考算法模板/最小生成树/最小生成树_Prim(稠密图)..cpp
Normal file
@ -0,0 +1,62 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
struct edge {
|
||||
int to, w;
|
||||
} a[10001];
|
||||
|
||||
int dis[101];
|
||||
int ans, cnt;
|
||||
vector<edge> graph[101];
|
||||
bool visit[101];
|
||||
struct cmp //·Âº¯Êý
|
||||
{
|
||||
bool operator()(const edge &a, const edge &b) {
|
||||
return a.w > b.w;
|
||||
}
|
||||
};
|
||||
priority_queue<edge, vector<edge>, cmp> pq;
|
||||
int main() {
|
||||
int n,m,k;
|
||||
cin>>n>>m;
|
||||
|
||||
for (int j = 1; j <= m; j++) {
|
||||
int a,b,c;
|
||||
cin>>a>>b>>c;
|
||||
graph[a].push_back({b,c});
|
||||
graph[b].push_back({a,c});
|
||||
}
|
||||
for (int i = 1; i <= n; i++) {
|
||||
dis[i]=INT_MAX/2;
|
||||
}
|
||||
visit[1]=true;
|
||||
for(int i=0;i<graph[1].size();i++)
|
||||
{
|
||||
edge e=graph[1][i];
|
||||
dis[e.to]=e.w;
|
||||
}
|
||||
|
||||
pq.push({1, 0});
|
||||
|
||||
while (!pq.empty()) {
|
||||
//todo
|
||||
}
|
||||
cout << ans << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
6 9
|
||||
2 4 11
|
||||
3 5 13
|
||||
4 6 3
|
||||
5 6 4
|
||||
2 3 6
|
||||
4 5 7
|
||||
1 2 1
|
||||
3 4 9
|
||||
1 3 2
|
||||
*/
|
||||
|
||||
|
||||
|
82
20240919/CSP常考算法模板/最小生成树/最小生成树_kruskal(稀疏图).cpp
Normal file
82
20240919/CSP常考算法模板/最小生成树/最小生成树_kruskal(稀疏图).cpp
Normal file
@ -0,0 +1,82 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
struct edge {
|
||||
int x, y, w;
|
||||
} a[10001];
|
||||
|
||||
int f[101];
|
||||
int ans, cnt;
|
||||
|
||||
bool cmp(edge x, edge y) {
|
||||
return x.w < y.w;
|
||||
}
|
||||
|
||||
//int getDistance(int x1, int y1, int x2, int y2) {
|
||||
// return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2); // 最后要求距离的平方
|
||||
//}
|
||||
|
||||
int n, m;
|
||||
int find(int x) {
|
||||
if (x == f[x])
|
||||
return x;
|
||||
return f[x]=find(f[x]);
|
||||
}
|
||||
|
||||
void merge(int x, int y) {
|
||||
int fx = find(x);
|
||||
int fy = find(y);
|
||||
if (fx != fy) {
|
||||
//如果不在一个集合
|
||||
f[fy] = fx;
|
||||
}
|
||||
}
|
||||
void kruskal()
|
||||
{
|
||||
for (int i = 1; i <= n; i++) {
|
||||
f[i] = i;
|
||||
}
|
||||
for (int i = 1; i <= m; i++) {
|
||||
int u=a[i].x;
|
||||
int v=a[i].y;
|
||||
if(find(u)!=find(v))
|
||||
{
|
||||
cnt++;
|
||||
ans+=a[i].w;
|
||||
merge(u,v);
|
||||
}
|
||||
if(cnt==n-1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
cin>>n>>m;
|
||||
|
||||
for (int j = 1; j <= m; j++) {
|
||||
cin>>a[j].x>>a[j].y>>a[j].w;
|
||||
}
|
||||
sort(a + 1, a + m + 1, cmp); //排序
|
||||
kruskal();
|
||||
cout << ans << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
6 9
|
||||
2 4 11
|
||||
3 5 13
|
||||
4 6 3
|
||||
5 6 4
|
||||
2 3 6
|
||||
4 5 7
|
||||
1 2 1
|
||||
3 4 9
|
||||
1 3 2
|
||||
*/
|
||||
|
||||
|
||||
|
65
20240919/CSP常考算法模板/最短路径/单源最短路径Dijkstra.cpp
Normal file
65
20240919/CSP常考算法模板/最短路径/单源最短路径Dijkstra.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
const int N = 2501;
|
||||
const int M = 15001;
|
||||
|
||||
struct point {
|
||||
int id;
|
||||
int len;
|
||||
};
|
||||
|
||||
vector<point> g[N];
|
||||
int t, c, ts, te;
|
||||
int rs, re, ci;
|
||||
int dis[N];
|
||||
bool vis[N];
|
||||
|
||||
struct cmp //仿函数
|
||||
{
|
||||
bool operator()(point a, point b) {
|
||||
return a.len > b.len; //priority_queue的排序规则与sort的规则相反
|
||||
}
|
||||
};
|
||||
|
||||
priority_queue<point, vector<point>, cmp> pq;
|
||||
|
||||
void Dijkstra()
|
||||
{
|
||||
memset(dis, 0x3f, sizeof(dis));
|
||||
dis[ts] = 0; // 注意起 始点是ts!!!
|
||||
pq.push({ts, 0});
|
||||
|
||||
while (pq.size()>0) {
|
||||
int id = pq.top().id; // 取出当前距离源点最近的点
|
||||
pq.pop();
|
||||
|
||||
if (vis[id]) continue;
|
||||
vis[id] = 1;
|
||||
|
||||
for (point e:g[id]) {
|
||||
|
||||
if (dis[e.id] > dis[id] + e.len) {
|
||||
dis[e.id] = dis[id] + e.len;
|
||||
pq.push({e.id, dis[e.id]});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
ios::sync_with_stdio(false);
|
||||
cin.tie(0);
|
||||
|
||||
cin >> t >> c >> ts >> te;
|
||||
for (int i = 0; i < c; i++) {
|
||||
cin >> rs >> re >> ci;
|
||||
g[rs].push_back({re,ci});
|
||||
g[re].push_back({rs,ci});
|
||||
}
|
||||
|
||||
Dijkstra();
|
||||
|
||||
cout << dis[te] << endl;
|
||||
return 0;
|
||||
}
|
61
20240919/CSP常考算法模板/最短路径/单源最短路径SPFA(有负边).cpp
Normal file
61
20240919/CSP常考算法模板/最短路径/单源最短路径SPFA(有负边).cpp
Normal file
@ -0,0 +1,61 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
int dis[2501];
|
||||
bool exist[2501];//标记每个点是否在queue中
|
||||
struct point
|
||||
{
|
||||
int to;
|
||||
int w;
|
||||
};
|
||||
int n,m,s,t;
|
||||
vector<point> graph[2501];
|
||||
|
||||
void SPFA()
|
||||
{
|
||||
memset(dis, 0x3f, sizeof(dis));
|
||||
dis[s] = 0; // 注意起 始点是s!!!
|
||||
queue<int> q;
|
||||
q.push(s);
|
||||
exist[s]=1;
|
||||
|
||||
while(q.size()>0)
|
||||
{
|
||||
int from=q.front();
|
||||
q.pop();
|
||||
exist[from]=0;
|
||||
for(int i=0;i<graph[from].size();i++)
|
||||
{
|
||||
// for(int temp:graph[from])
|
||||
|
||||
int to=graph[from][i].to;
|
||||
int w=graph[from][i].w;
|
||||
if(dis[from]+w<dis[to])
|
||||
{
|
||||
dis[to]=dis[from]+w;
|
||||
if(exist[to]==0)
|
||||
{
|
||||
q.push(to);
|
||||
exist[to]=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
ios::sync_with_stdio(false);
|
||||
cin.tie(0);
|
||||
|
||||
cin >> n >> m >> s >> t;
|
||||
for (int i = 1; i <=m ; i++) {
|
||||
int a,b,c;
|
||||
cin >> a >> b >> c;
|
||||
graph[a].push_back({b,c});
|
||||
graph[b].push_back({a,c});
|
||||
}
|
||||
|
||||
SPFA();
|
||||
|
||||
cout << dis[t] << endl;
|
||||
return 0;
|
||||
}
|
58
20240919/CSP常考算法模板/最短路径/多源最短路径Floyed.cpp
Normal file
58
20240919/CSP常考算法模板/最短路径/多源最短路径Floyed.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
int a[101][3];
|
||||
double f[101][101];
|
||||
int n,i,j,k,x,y,m,s,e;
|
||||
int main()
|
||||
{
|
||||
// freopen("short.in","r",stdin);
|
||||
// freopen("short.out","w",stdout);
|
||||
cin >> n;
|
||||
for (i = 1; i <= n; i++)
|
||||
cin >> a[i][1] >> a[i][2];
|
||||
cin >> m;
|
||||
memset(f,0x7f,sizeof(f)); //初始化f数组为最大值
|
||||
|
||||
//预处理出x、y间距离
|
||||
// for (i = 1; i <= m; i++)
|
||||
// {
|
||||
// cin >> x >> y;
|
||||
// f[y][x] = f[x][y] = sqrt(pow(a[x][1]-a[y][1],2)+pow(a[x][2]-a[y][2],2));
|
||||
// //pow(x,y)表示x^y,其中x,y必须为double类型,要用cmath库
|
||||
// }
|
||||
|
||||
for (i = 1; i <= n; i++)
|
||||
f[i][i]=0;
|
||||
cin >> s >> e;
|
||||
for (k = 1; k <= n; k++) //k表示中转点 //floyed 最短路算法
|
||||
{
|
||||
for (i = 1; i <= n; i++)
|
||||
{
|
||||
for (j = 1; j <= n; j++)
|
||||
{
|
||||
if (f[i][k]+f[k][j] < f[i][j])
|
||||
f[i][j] = f[i][k] + f[k][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("%.2lf\n",f[s][e]);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
5
|
||||
0 0
|
||||
2 0
|
||||
2 2
|
||||
0 2
|
||||
3 1
|
||||
5
|
||||
1 2
|
||||
1 3
|
||||
1 4
|
||||
2 5
|
||||
3 5
|
||||
1 5
|
||||
*/
|
||||
|
||||
|
54
20240919/CSP常考算法模板/树上问题_dfs.cpp
Normal file
54
20240919/CSP常考算法模板/树上问题_dfs.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
const int MAXN = 1e5 + 5;
|
||||
|
||||
//dep[u]代表u的深度
|
||||
//leaf[u]代表以u为根的子树中,深度最浅的那个叶子节点的深度。
|
||||
int n , m , rt , leaf[MAXN] , dep[MAXN];
|
||||
|
||||
vector<int> graph[MAXN];
|
||||
|
||||
// 算出dep[u]和leaf[u]
|
||||
int dfs(int u, int fa) { // 返回距离u点最近的叶子节点深度
|
||||
dep[u] = dep[fa] + 1;
|
||||
// u是叶子节点
|
||||
if(graph[u].size()==1) {
|
||||
leaf[u] = dep[u];
|
||||
return leaf[u];
|
||||
}
|
||||
for(int v : graph[u]) {
|
||||
if(v == fa) continue;
|
||||
|
||||
leaf[u] = min(dfs(v , u) , leaf[u]);
|
||||
}
|
||||
return leaf[u];
|
||||
}
|
||||
|
||||
// 节点u能够被控制所需的farmer数量
|
||||
int dfs2(int u, int fa) {
|
||||
if(dep[u] - 1 >= leaf[u] - dep[u]) return 1;
|
||||
int cnt = 0;
|
||||
for (int v : graph[u]) {
|
||||
if (v == fa) continue;
|
||||
cnt += dfs2(v, u);
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
int main() {
|
||||
// freopen("atlarge.in", "r", stdin);
|
||||
// freopen("atlarge.out", "w", stdout);
|
||||
|
||||
memset(leaf , 0x3f , sizeof(leaf));
|
||||
scanf("%d%d" , &n, &rt);
|
||||
for(int i = 0; i < n - 1 ; i++) {
|
||||
int u, v;
|
||||
scanf("%d%d" , &u , &v);
|
||||
graph[u].push_back(v);
|
||||
graph[v].push_back(u);
|
||||
}
|
||||
dfs(rt , 0);
|
||||
printf("%d\n" , dfs2(rt, 0));
|
||||
return 0;
|
||||
}
|
46
20240919/CSP常考算法模板/树状数组/树状数组( 单点修改 区间查询).cpp
Normal file
46
20240919/CSP常考算法模板/树状数组/树状数组( 单点修改 区间查询).cpp
Normal file
@ -0,0 +1,46 @@
|
||||
#include <bits/stdc++.h>
|
||||
#define ll long long
|
||||
using namespace std;
|
||||
|
||||
const int MAXN = 1e6 + 10;
|
||||
ll c[MAXN];
|
||||
int n, q, k, a, b;
|
||||
|
||||
int lowbit(int x) {
|
||||
return x&(-x);
|
||||
}
|
||||
|
||||
void update(int x, int v) {
|
||||
for(int i=x;i<=n;i+=lowbit(i))
|
||||
c[i]+=v;
|
||||
}
|
||||
|
||||
ll getSum(int x) {
|
||||
ll ans=0;
|
||||
for(int i=x; i>0; i-=lowbit(i))
|
||||
ans+=c[i];
|
||||
return ans;
|
||||
}
|
||||
|
||||
int main() {
|
||||
ios::sync_with_stdio(false);
|
||||
cin.tie(0);
|
||||
|
||||
int v;
|
||||
cin>>n>>q;
|
||||
for(int i=1; i<=n; i++) {
|
||||
cin>>v;
|
||||
update(i, v);
|
||||
}
|
||||
|
||||
for(int i=1; i<=q; i++) {
|
||||
cin>>k>>a>>b;
|
||||
if(k==1) {
|
||||
update(a, b);
|
||||
} else {
|
||||
cout<<getSum(b)-getSum(a-1)<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
BIN
20240919/CSP常考算法模板/树状数组/树状数组.pdf
Normal file
BIN
20240919/CSP常考算法模板/树状数组/树状数组.pdf
Normal file
Binary file not shown.
39
20240919/CSP常考算法模板/树的先序排列.cpp
Normal file
39
20240919/CSP常考算法模板/树的先序排列.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
void preOrder(string in,string post){
|
||||
if(in.length() == 0) {
|
||||
return;
|
||||
}
|
||||
char root=post[post.size()-1];
|
||||
cout<<root; //输出根节点
|
||||
int k=in.find(root);
|
||||
|
||||
//递归左右子树
|
||||
preOrder(in.substr(0, k), post.substr(0, k));
|
||||
preOrder(in.substr(k+1), post.substr(k, in.size()-k-1));
|
||||
}
|
||||
|
||||
void postOrder(string pre, string in)
|
||||
{
|
||||
if (pre.length() == 0) {
|
||||
return;
|
||||
}
|
||||
char root = pre[0];
|
||||
int k = in.find(root);
|
||||
//递归左右子树
|
||||
postOrder(pre.substr(1, k), in.substr(0, k));
|
||||
postOrder(pre.substr(k+1), in.substr(k+1));
|
||||
putchar(root); //输出根节点
|
||||
}
|
||||
|
||||
int main(){
|
||||
ios::sync_with_stdio(false);
|
||||
cin.tie(0);
|
||||
|
||||
string inOrder, postOrder;
|
||||
cin>>inOrder>>postOrder;
|
||||
preOrder(inOrder, postOrder);
|
||||
cout<<endl;
|
||||
return 0;
|
||||
}
|
87
20240919/CSP常考算法模板/树的存储和搜索.cpp
Normal file
87
20240919/CSP常考算法模板/树的存储和搜索.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
vector<int> g[200010];
|
||||
|
||||
long long hay[200010];
|
||||
struct node
|
||||
{
|
||||
int to;
|
||||
long long w;
|
||||
};
|
||||
vector<node> m[200010];
|
||||
long long avg = 0;
|
||||
int ans = 0;
|
||||
int indegree[200010];
|
||||
|
||||
void dfs(int u, int f) {
|
||||
for (int v : g[u]) {
|
||||
if (v != f)
|
||||
{
|
||||
dfs(v, u);
|
||||
}
|
||||
}
|
||||
if(hay[u]==avg)
|
||||
return;
|
||||
|
||||
ans++;
|
||||
if (hay[u] > avg) {
|
||||
m[u].push_back({f, hay[u] - avg});
|
||||
hay[f] += hay[u] - avg;
|
||||
indegree[f]++;
|
||||
} else {
|
||||
hay[f] -= avg-hay[u];
|
||||
m[f].push_back({u, avg-hay[u]});
|
||||
indegree[u]++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
首先dfs找到每条边搬多少,然后有个细节是如果直接做可能出现负数,
|
||||
所以要再用一个bfs,先从没有入度的点开始走,避免这种情况
|
||||
*/
|
||||
int main() {
|
||||
int n;
|
||||
cin >> n;
|
||||
for (int i = 1; i <= n; i++) {
|
||||
scanf("%lld", &hay[i]);
|
||||
avg += hay[i];
|
||||
}
|
||||
|
||||
avg /= n;
|
||||
for (int i = 1; i < n; i++) {
|
||||
int a, b;
|
||||
cin>>a>>b;
|
||||
g[a].push_back(b);
|
||||
g[b].push_back(a);
|
||||
}
|
||||
|
||||
dfs(1, 0);
|
||||
cout << ans << endl;
|
||||
queue<int> q;
|
||||
|
||||
for (int i = 1; i <= n; i++)
|
||||
{
|
||||
if (indegree[i] == 0)
|
||||
{
|
||||
q.push(i);
|
||||
}
|
||||
}
|
||||
while(q.size()>0)
|
||||
{
|
||||
int cur=q.front();
|
||||
q.pop();
|
||||
for(node i:m[cur])
|
||||
{
|
||||
cout<<cur<<" "<<i.to<<" "<<i.w<<endl;
|
||||
indegree[i.to]--;
|
||||
if(indegree[i.to]==0)
|
||||
{
|
||||
q.push(i.to);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
32
20240919/CSP常考算法模板/混合背包.cpp
Normal file
32
20240919/CSP常考算法模板/混合背包.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
int m, n;
|
||||
int w[31], c[31], p[31];
|
||||
int f[201];
|
||||
|
||||
/*
|
||||
10 3
|
||||
2 1 0
|
||||
3 3 1
|
||||
4 5 4
|
||||
*/
|
||||
|
||||
int main(){
|
||||
scanf("%d%d",&m,&n);
|
||||
for (int i = 1; i <= n; i++)
|
||||
scanf("%d%d%d",&w[i],&c[i],&p[i]);
|
||||
for (int i = 1; i <= n; i++)
|
||||
if (p[i] == 0) { //完全背包
|
||||
for (int j = w[i]; j <= m; j++)
|
||||
f[j] = max(f[j], f[j-w[i]]+c[i]);
|
||||
}
|
||||
else {
|
||||
for (int j = 1; j <= p[i]; j++) //01背包和多重背包
|
||||
for (int k = m; k >= w[i]; k--)
|
||||
f[k] = max(f[k],f[k-w[i]]+c[i]);
|
||||
}
|
||||
|
||||
printf("%d",f[m]);
|
||||
return 0;
|
||||
}
|
||||
|
62
20240919/CSP常考算法模板/线性dp_求最长不下降序列_逆推.cpp
Normal file
62
20240919/CSP常考算法模板/线性dp_求最长不下降序列_逆推.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
#include<bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
int a[100], dp[100], trace[100];
|
||||
|
||||
/*
|
||||
14
|
||||
13 7 9 16 38 24 37 18 44 19 21 22 63 15
|
||||
|
||||
输出
|
||||
max=8
|
||||
7 9 16 18 19 21 22 63
|
||||
*/
|
||||
int main()
|
||||
{
|
||||
int n;
|
||||
cin>>n;
|
||||
for(int i=1; i<=n; i++)
|
||||
{
|
||||
cin>>a[i]; // 原始数据
|
||||
dp[i]=1; // LIS
|
||||
trace[i]=0; // 上一个数的位置
|
||||
}
|
||||
|
||||
// 求LIS
|
||||
for(int i=n-1; i>=1; i--)
|
||||
{
|
||||
int maxlis=0;
|
||||
int maxindex=0;
|
||||
for(int j=i+1; j<=n; j++)
|
||||
{
|
||||
if(a[j]>a[i] && dp[j]>maxlis)
|
||||
{
|
||||
maxlis=dp[j];
|
||||
maxindex=j;
|
||||
}
|
||||
}
|
||||
|
||||
if(maxlis>0)
|
||||
{
|
||||
dp[i]=maxlis+1;
|
||||
trace[i]=maxindex;
|
||||
}
|
||||
}
|
||||
|
||||
int pos=1;
|
||||
for(int i=2; i<=n; i++)
|
||||
{
|
||||
if(dp[i]>dp[pos])
|
||||
pos=i;
|
||||
}
|
||||
cout<<"max="<<dp[pos]<<endl;
|
||||
|
||||
// 输出最长不下降序列
|
||||
while(pos!=0)
|
||||
{
|
||||
cout<<a[pos]<<" ";
|
||||
pos=trace[pos];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
71
20240919/CSP常考算法模板/线段树(区间修改,区间查询).cpp
Normal file
71
20240919/CSP常考算法模板/线段树(区间修改,区间查询).cpp
Normal file
@ -0,0 +1,71 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
#define LL long long
|
||||
|
||||
const int SIZE = 1e6;
|
||||
|
||||
struct node{
|
||||
int l, r;
|
||||
LL w; // 区间和
|
||||
};
|
||||
|
||||
node tree[4*SIZE + 1]; // 开4倍大小
|
||||
|
||||
inline void build(int k, int l, int r) { // k代表当前节点编号
|
||||
tree[k].l = l;
|
||||
tree[k].r = r;
|
||||
if (l == r) { // 叶子节点
|
||||
scanf("%lld", &tree[k].w);
|
||||
return;
|
||||
}
|
||||
int mid = l + r >> 1; // 相当于 (l + r) >> 1 k
|
||||
int lc = k << 1, rc = lc | 1;
|
||||
build(lc, l, mid); // 左子树
|
||||
build(rc, mid + 1, r); // 右子树
|
||||
tree[k].w = tree[lc].w + tree[rc].w;
|
||||
}
|
||||
|
||||
// 单点修改
|
||||
inline void changePoint(int k, int x, int c) {
|
||||
if (tree[k].l == tree[k].r) { // 找到叶子节点
|
||||
tree[k].w += c;
|
||||
return;
|
||||
}
|
||||
int mid = tree[k].l + tree[k].r >> 1;
|
||||
int lc = k << 1, rc = lc | 1;
|
||||
if (x <= mid)
|
||||
changePoint(lc, x, c);
|
||||
else
|
||||
changePoint(rc, x, c);
|
||||
tree[k].w = tree[lc].w + tree[rc].w;
|
||||
}
|
||||
|
||||
// 区间查询
|
||||
inline LL queryInterval(int k, int L, int R) {
|
||||
if (tree[k].l >= L && tree[k].r <= R)
|
||||
return tree[k].w;
|
||||
|
||||
int mid = tree[k].l + tree[k].r >> 1;
|
||||
int lc = k<<1, rc = lc | 1;
|
||||
LL ans = 0;
|
||||
if (L <= mid)
|
||||
ans += queryInterval(lc, L, R);
|
||||
if (R > mid)
|
||||
ans += queryInterval(rc, L, R);
|
||||
return ans;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int n, q;
|
||||
scanf("%d%d", &n, &q);
|
||||
build(1, 1, n);
|
||||
for (int i = 1; i <= q; i++) {
|
||||
int opt, x, y;
|
||||
scanf("%d%d%d", &opt, &x, &y);
|
||||
if (opt == 1)
|
||||
changePoint(1, x, y);
|
||||
if (opt == 2)
|
||||
printf("%lld\n", queryInterval(1, x, y));
|
||||
}
|
||||
return 0;
|
||||
}
|
32
20240919/CSP常考算法模板/背包问题_01.cpp
Normal file
32
20240919/CSP常考算法模板/背包问题_01.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
const int maxm = 201, maxn = 31;
|
||||
int m, n;
|
||||
int w[maxn], c[maxn];
|
||||
int f[maxn][maxm];
|
||||
|
||||
/*
|
||||
10 4
|
||||
2 1
|
||||
3 3
|
||||
4 5
|
||||
7 9
|
||||
*/
|
||||
int main(){
|
||||
ios::sync_with_stdio(false);
|
||||
cin.tie(0);
|
||||
|
||||
cin>>m>>n; //背包容量m和物品数量n
|
||||
for (int i = 1; i <= n; i++) //在初始化循环变量部分,定义一个变量并初始化
|
||||
cin>>w[i]>>c[i]; //每个物品的重量和价值
|
||||
for (int i = 1; i <= n; i++) // f[i][v]表示前i件物品,总重量不超过v的最优价值
|
||||
for (int v = m; v > 0; v--)
|
||||
if (w[i] <= v)
|
||||
f[i][v] = max(f[i-1][v],f[i-1][v-w[i]]+c[i]);
|
||||
else
|
||||
f[i][v] = f[i-1][v];
|
||||
cout<<f[n][m]<<endl; // f[n][m]为最优解
|
||||
return 0;
|
||||
}
|
||||
|
46
20240919/CSP常考算法模板/背包问题_多重.cpp
Normal file
46
20240919/CSP常考算法模板/背包问题_多重.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
int v[10001],w[10001];
|
||||
int f[6001];
|
||||
int n,m,n1;
|
||||
|
||||
/*
|
||||
【输入样例】
|
||||
5 1000
|
||||
80 20 4
|
||||
40 50 9
|
||||
30 50 7
|
||||
40 30 6
|
||||
20 20 1
|
||||
【输出样例】
|
||||
1040
|
||||
|
||||
*/
|
||||
int main() {
|
||||
scanf("%d%d",&n,&m);
|
||||
for(int i=1;i<=n;i++){
|
||||
int x,y,s,t=1;
|
||||
scanf("%d%d%d",&x,&y,&s);
|
||||
while (s>=t) {
|
||||
v[++n1]=x*t; //相当于n1++; v[n1]=x*t;
|
||||
w[n1]=y*t;
|
||||
s-=t;
|
||||
t*=2;
|
||||
}
|
||||
//把s以2的指数分堆:1,2,4,…,2^(k-1),s-2^k+1,
|
||||
if(s>0) {
|
||||
v[++n1]=x*s;
|
||||
w[n1]=y*s;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=1;i<=n1;i++)
|
||||
for(int j=m;j>=v[i];j--)
|
||||
f[j]=max(f[j],f[j-v[i]]+w[i]);
|
||||
printf("%d\n",f[m]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
20
20240919/CSP常考算法模板/背包问题_完全.cpp
Normal file
20
20240919/CSP常考算法模板/背包问题_完全.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int maxm=2001,maxn=31;
|
||||
int n,m,v,i;
|
||||
int c[maxn],w[maxn];
|
||||
int f[maxm];
|
||||
|
||||
int main()
|
||||
{
|
||||
scanf("%d%d",&m,&n); //背包容量m和物品数量n
|
||||
for(i=1;i<=n;i++)
|
||||
scanf("%d%d",&w[i],&c[i]);
|
||||
for(i=1;i<=n;i++)
|
||||
for(v=w[i];v<=m;v++) //设 f[v]表示重量不超过v公斤的最大价值
|
||||
if(f[v-w[i]]+c[i]>f[v])
|
||||
f[v]=f[v-w[i]]+c[i];
|
||||
printf("max=%d\n",f[m]); // f[m]为最优解
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user