P1194 买礼物
#include <bits/stdc++.h>
using namespace std;
int arr[5005][5005];
int brr[5005];
int crr[5005];
int main(){
int n,m,num=0;
memset(brr,0x7f,sizeof(brr));
cin>>n>>m;
brr[1]=n;
for (int i=1;i<=m;i++){
for(int j=1;j<=m;j++){
cin>>arr[i][j];
}
}
for (int i=1;i<=m;i++){
int k=0;
for (int j=1;j<=m;j++) {
if (!crr[j]&&brr[j]<brr[k]) k=j;
}
if(k==0) break;
crr[k]=1;
num+=brr[k];
for (int j=1;j<=m;j++) {
if(!crr[j]){
brr[j]=min(brr[j],n);
if (arr[k][j]<brr[j]&&arr[k][j]!=0) brr[j]=arr[k][j];
}
}
}
cout<<num;
return 0;
}
与P3366 【模板】最小生成树相似,通过prim算法,只不过在选取权值最小边时,需要注意判断权值为0与优惠价大于原价时,按原价出售。
P2872 [USACO07DEC] Building Roads S
#include<bits/stdc++.h>
using namespace std;
const int N=1000005;
struct point{
int x,y;
}p[N];
struct edge{
int u,v;
double w;
}e[N];
int fi[N];
int n,m,num=0;
double s;
bool cmp(edge a,edge b){
return a.w<b.w;
}
int find(int x){
if(fi[x]==x) return x;
else{
fi[x]=find(fi[x]);
return fi[x];
}
}
void kru(){
for(int i=1;i<=num;i++){
int f1=find(e[i].u);
int f2=find(e[i].v);
if(f1!=f2){
s+=e[i].w;
fi[f1]=f2;
}
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>p[i].x>>p[i].y;
}
for(int i=1;i<=n;i++){
fi[i]=i;
}
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
double z=sqrt((double)(p[i].x-p[j].x)*(p[i].x-p[j].x)+(double)(p[i].y-p[j].y)*(p[i].y-p[j].y));
e[++num].u=i;
e[num].v=j;
e[num].w=z;
}
}
for(int i=1;i<=m;i++){
cin>>e[++num].u>>e[num].v;
e[num].w=0.0;
}
sort(e+1,e+1+num,cmp);
kru();
printf("%.2lf",s);
return 0;
}
与P1991 无线通讯网相似,通过kruskal算法,但需要加上几条权值为0的边。
P1359 租用游艇
#include<bits/stdc++.h>
using namespace std;
int n,a[205][205],b[205];
int main(){
cin>>n;
for (int i=1;i<n;i++)
for(int j=i+1;j<=n;j++) cin>>a[i][j];
memset(b,0x7f,sizeof(b));
b[n]=0;
for(int i=n-1;i>=1;i--){
for(int j=i+1;j<=n;j++){
b[i]=min(b[i],a[i][j]+b[j]);
}
}
cout<<b[1];
return 0;
}