【洛谷P1194】买礼物
今天因为加睡了,也要加训!
看一下这道最小生成树的题目
其实也算是板子()
P1194 买礼物
题目描述
又到了一年一度的明明生日了,明明想要买 \(B\) 样东西,巧的是,这 \(B\) 样东西价格都是 \(A\) 元。
但是,商店老板说最近有促销活动,也就是:
如果你买了第 \(I\) 样东西,再买第 \(J\) 样,那么就可以只花 \(K_{I,J}\) 元,更巧的是,\(K_{I,J}\) 竟然等于 \(K_{J,I}\)。
现在明明想知道,他最少要花多少钱。
输入格式
第一行两个整数,\(A,B\)。
接下来 \(B\) 行,每行 \(B\) 个数,第 \(I\) 行第 \(J\) 个为 \(K_{I,J}\)。
我们保证 \(K_{I,J}=K_{J,I}\) 并且 \(K_{I,I}=0\)。
特别的,如果 \(K_{I,J}=0\),那么表示这两样东西之间不会导致优惠。
注意 \(K_{I,J}\) 可能大于 \(A\)。
输出格式
一个整数,为最小要花的钱数。
输入输出样例 #1
输入 #1
1 1
0
输出 #1
1
输入输出样例 #2
输入 #2
3 3
0 2 4
2 0 2
4 2 0
输出 #2
7
说明/提示
样例解释 \(2\)。
先买第 \(2\) 样东西,花费 \(3\) 元,接下来因为优惠,买 \(1,3\) 样都只要 \(2\) 元,共 \(7\) 元。
(同时满足多个“优惠”的时候,聪明的明明当然不会选择用 \(4\) 元买剩下那件,而选择用 \(2\) 元。)
数据规模
对于 \(30\%\) 的数据,\(1\le B\le 10\)。
对于 \(100\%\) 的数据,\(1\le B\le500,0\le A,K_{I,J}\le1000\)。
2018.7.25新添数据一组
解法&&个人感想
意思是说,这道题里面由于可以单独买某件物品
那如果连边连的是自环的话 在getx gety 这边就会因为相等被排掉
那怎么办?
我们还是可以采用超级源点的意识 用0/n+1 看个人洗好去连接每个点 权值就是自环的值
再跑一遍Kruscal 就可以了
下面是代码:
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define maxn 2505
#define maxm 250005
using namespace std;
struct Edge{
int from,to,w;
};
Edge edge[maxm];
int fa[maxm];
int n,m;
int ma[maxn][maxn];
int cnt=0;
ll ans=0;
bool cmp(Edge x,Edge y){
return x.w<y.w;
}
int get(int x){
if(fa[x]==x) return x;
return fa[x]=get(fa[x]);
}
void merge(int x,int y){
fa[x]=y;
return ;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
for(int j=1;j<=m;j++){
scanf("%d",&ma[i][j]);
}
}
for(int i=1;i<=m;i++){
for(int j=1;j<=m;j++){
if(i>=j||ma[i][j]==0) continue;
edge[++cnt].from=i;
edge[cnt].to=j;
edge[cnt].w=ma[i][j];
}
}
for(int i=1;i<=m;i++){
edge[++cnt].from=0;
edge[cnt].to=i;
edge[cnt].w=n;
}
sort(edge+1,edge+1+cnt,cmp);
for(int i=0;i<=m;i++) fa[i]=i;
for(int i=1;i<=cnt;i++){
int x=get(edge[i].from),y=get(edge[i].to);
if(x==y) continue;
ans+=edge[i].w;
merge(x,y);
}
printf("%lld\n",ans);
system("pause");
return 0;
}
篇末传统艺能


浙公网安备 33010602011771号