题目描述
又到了一年一度的明明生日了,明明想要买BB样东西,巧的是,这BB样东西价格都是AA元。
但是,商店老板说最近有促销活动,也就是:
如果你买了第II样东西,再买第JJ样,那么就可以只花K_{I,J}K
I,J
元,更巧的是,K_{I,J}K
I,J
竟然等于K_{J,I}K
J,I
。
现在明明想知道,他最少要花多少钱。
输入格式
第一行两个整数,A,BA,B。
接下来BB行,每行BB个数,第II行第JJ个为K_{I,J}K
I,J
。
我们保证K_{I,J}=K_{J,I}K
I,J
=K
J,I
并且K_{I,I}=0K
I,I
=0。
特别的,如果K_{I,J}=0K
I,J
=0,那么表示这两样东西之间不会导致优惠。
输出格式
一个整数,为最小要花的钱数。
输入输出样例
输入 #1复制
1 1
0
输出 #1复制
1
输入 #2复制
3 3
0 2 4
2 0 2
4 2 0
输出 #2复制
7
说明/提示
样例解释22
先买第22样东西,花费33元,接下来因为优惠,买1,31,3样都只要22元,共77元。
(同时满足多个“优惠”的时候,聪明的明明当然不会选择用44元买剩下那件,而选择用22元。)
数据规模
对于30%30%的数据,1 \le B \le 101≤B≤10。
对于100%100%的数据,1 \le B \le 500,0 \le A,K_{I,J} \le 10001≤B≤500,0≤A,K
I,J
≤1000。
思路:先求出最小生成树再加上一个原价(因为第一个买的没优惠)
注意:在洛谷题解中我看到这样一组if(i<=j&&x!=0),本来我以为我理解错了,后来发现x==0可能只是跟正常人理解不太一样qaq
如果有优惠就建边然后跑一遍kruskal就行了
#include<bits/stdc++.h>
using namespace std;
const int N=500+10;
int pr[N][N];
int a,b;
const int INF=0x3f3f3f3f;
int dis[N];
bool jud[N];
int pri;
void prim(){
for(int i=0;i<b+1;i++){
int t=-1;
for(int j=0;j<=b;j++){
if(!jud[j]&&(t==-1||dis[j]<dis[t])){
t=j;
}
}
jud[t]=1;
if(i){
pri+=dis[t];
}
for(int j=0;j<=b;j++){
dis[j]=min(dis[j],pr[t][j]);
}
}
}
int main(){
cin>>a>>b;
for(int i=1;i<=b;i++){
for(int j=1;j<=b;j++){
cin>>pr[i][j];
if(pr[i][j]==0&&i!=j){
pr[i][j]=INF;
}
}
}
for(int i=1;i<=b;i++){
pr[0][i]=a;
}
memset(dis,0x3f,sizeof dis);
prim();
cout<<pri;
return 0;
}