1. 程式人生 > >洛谷——P1194 買禮物

洛谷——P1194 買禮物

content copy clu 輸入輸出 data- 之間 con names space

P1194 買禮物

題目描述

又到了一年一度的明明生日了,明明想要買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,J?1000。

2018.7.25新添數據一組

其實這題不這樣做也可以,跑一邊最小生成樹,再加上a即可,相當於你先使用a元買一個物品,剩余的

物品可以由這個物品拓展出來,不過有個坑,就是最後一個點的促銷的值要比原價要高,取個min即可。

#include<bits/stdc++.h>

#define N 5100
using namespace std;

int a,b,g[5010][5050],minn[N],n;
bool vis[N];
long long ans;
int main()
{
    scanf("%d%d",&a,&b);
    for(int i=1;i<=b;i++)
        for(int j=1;j<=b;j++){
            scanf("%d",&g[i][j]);
            if(!g[i][j]) g[i][j]=0x7fffffff;
        }
    for(int i=0;i<=b;i++)    
        g[b+1][i]=a,g[i][b+1]=0x7fffffff;
    memset(minn,0x7f,sizeof(minn));
    n=b+1;
    int k=0;minn[n]=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(minn[j]<minn[k]&&!vis[j]) k=j;
        }
        vis[k]=1;
        for(int j=1;j<=n;j++){
            if(!vis[j]&&minn[j]>g[k][j])
                minn[j]=g[k][j];
        }k=0;
    }
    for(int i=1;i<=n;i++)
        ans+=minn[i];
    printf("%lld\n",ans);
    return 0;
}

洛谷——P1194 買禮物