一)前缀和
一次循环求出序列的每一个前缀的和
#include <bits/stdc++.h>
using namespace std;
int a[100];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
a[i]+=a[i-1];
}
for(int i=1;i<=n;i++){
cout<<a[i]<<" ";
}
return 0;
}
二)最短路计数
way[ ]从S点到way[i]点的最短方案数
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2100;
vector <pair<ll,ll>> vc[maxn];
const ll inf=1e15;
ll dist[maxn],bk[maxn],way[maxn];
int main()
{
int n,m;
cin>>n>>m;
for(int i=1; i<=m; i++){
int x,y,z;
cin>>x>>y>>z;
vc[x].push_back(make_pair(y,z));
vc[y].push_back(make_pair(x,z));
}
int s;cin>>s;
for(int i=1; i<=n; i++)
dist[i]=inf;
dist[s]=0;
way[s]=1;
for(int i=1; i<=n; i++){
ll mi=inf,x;
for(int j=1; j<=n; j++){
if(bk[j])
continue;
if(mi>dist[j]){
mi=dist[j];
x=j;
}
}
bk[x]=1;
for(auto g:vc[x]){
ll v=g.first,w=g.second;
dist[v]=min(dist[v],dist[x]+w);
if(dist[v]<dist[x]+w){
continue;
}
else if(dist[v]>dist[x]+w){
dist[v]=dist[x]+w;
way[v]=way[x];
}else{
way[v]+=way[x];
}
}
}
/* for(int i=1;i<=n;i++)
cout<<s<<" -> "<<i<<" "<<dist[i]<<endl;*/
for(int i=1;i<=n;i++)
cout<<s<<" -> "<<i<<" "<<way[i]<<endl;
return 0;
}
三)树上DP
1、无环无向图
2、树的直径
1、x和y一定是叶子节点
2、LCA最近公共祖先
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2000 + 5;
// 求树的直径
vector<int> e[maxn];
int dp[maxn] , f[maxn];
// dfs1求dp,含义为从i到它的子树的叶子节点的最长路径
void dfs1(int u , int fa){
dp[u] = 0;
for (auto v : e[u]){
if (v == fa) continue;
dfs1(v , u);
dp[u] = max(dp[u] , dp[v]);
}
dp[u] += 1; // 加本身
return ;
}
// dfs2求f,含义为LCA(x,y) = i 的所有路径中的最长路径
// 树的直径就为 max{f[i]}
void dfs2 (int u , int fa){
vector<int> tmp;
for (auto v : e[u]){
if (v == fa) continue;
dfs2(v , u);
tmp.push_back(dp[v]);
}
// 降序排序
sort(tmp.begin() , tmp.end());
reverse(tmp.begin() , tmp.end());
if (tmp.size() == 0){ // 没有儿子,叶子节点咋办
f[u] = 1;
}
else if (tmp.size() == 1){// 如果只有一个儿子,咋办?
f[u] = tmp[0] + 1;
}else {
f[u] = tmp[0] + tmp[1] + 1;
}
return ;
}
int main()
{
int n; cin >> n;
for (int i = 1 ; i <= n - 1 ; i++){
int x , y; cin >> x >> y;
e[x].push_back(y);
e[y].push_back(x);
}
dfs1(1 , -1);
dfs2(1 , -1);
cout << *max_element(f + 1 , f + 1 + n) << endl;
return 0;
}