【洛谷 1194】买礼物

展开

题目描述

又到了一年一度的明明生日了,明明想要买BB样东西,巧的是,这BB样东西价格都是AA元。

但是,商店老板说最近有促销活动,也就是:

如果你买了第II样东西,再买第JJ样,那么就可以只花K_{I,J}KI,J元,更巧的是,K_{I,J}KI,J竟然等于K_{J,I}KJ,I

现在明明想知道,他最少要花多少钱。

输入格式

第一行两个整数,A,BA,B。

接下来BB行,每行BB个数,第II行第JJ个为K_{I,J}KI,J

我们保证K_{I,J}=K_{J,I}KI,J=KJ,I并且K_{I,I}=0KI,I=0。

特别的,如果K_{I,J}=0KI,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 101B10。

对于100\%100%的数据,1 \le B \le 500,0 \le A,K_{I,J} \le 10001B500,0A,KI,J1000。

2018.7.25新添数据一组

 

题解:最后要加上单价(虽然不知道为啥,但加上就对了)printf("%d",ans+n);

 

#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<cstdio>
using namespace std;
typedef double db;
const int N=200005;
int n,m,cp,tot,fa[N],b[N];
struct YCLL{
    int u,v;
    int va;
}e[N];
int ans=0;
bool cmp(YCLL aa,YCLL bb){
    return aa.va<bb.va;
}

int find(int x){
    if(x!=fa[x]) 
       fa[x]=find(fa[x]);
    return fa[x];
}
int main(){
    freopen("1194.in","r",stdin);
    freopen("11194.out","w",stdout);
    scanf("%d %d",&n,&m); 
    for(int i=1;i<=m;i++) fa[i]=i;
    for(int i=1;i<=m;i++){
        for(int j=1;j<=m;j++){
            int val; scanf("%d",&val);
            if(i<=j && val!=0) {
               cp++; e[cp].va=val;
               e[cp].u=i; e[cp].v=j;
            }    
        }
    }
    sort(e+1,e+cp+1,cmp);
    for(int i=1;i<=cp;i++){
        int uu=find(e[i].u);
        int vv=find(e[i].v);
        if(uu==vv) continue;
        ans+=min(n,e[i].va); 
        fa[uu]=vv; //tot++;
        //if(tot==(n-1)) break;
    }
    printf("%d",ans+n);
    return 0;
}

 

posted @ 2019-08-03 21:35  #Cookies#  阅读(220)  评论(0编辑  收藏  举报