对序列求前缀和
其实这题最关键的就是我们只要知道了【a,b】和【b,c】就可以知道了【a,c】
实际上这和两点之间有且仅有一条路径是相似的,由此联想了一个最小生成树模型。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
using namespace std;
typedef long long ll;
int n,tot;
int fa[2205];
struct aa
{
int u,v;
ll dis;
bool operator <(const aa &b)const
{
return dis<b.dis;
}
}bian[2005*2005];
int find(int u)
{
return u==fa[u]?u:fa[u]=find(fa[u]);
}
int main()
{
scanf("%d",&n);
for (int i=0;i<=n;i++) fa[i]=i;
ll x;
for (int i=1;i<=n;i++)
{
for (int j=i;j<=n;j++)
{
scanf("%lld",&x);
bian[++tot].dis=x;bian[tot].u=i-1;bian[tot].v=j;
}
}
sort(bian+1,bian+tot+1);
ll ans=0,kk=0;
for (int i=1;i<=tot;i++)
{
int fu=find(bian[i].u),fv=find(bian[i].v);
if (fu!=fv)
{
ans+=bian[i].dis;
fa[fu]=fv;
kk++;if (kk==n) break;
}
}
printf("%lld",ans);
return 0;
}
总结
1:对于一些两点之间信息只需要保留一个问题可以考虑用最小生成树
2:善于联想,考虑一些问题之间潜在的联系性,尝试模型的转化。