zoukankan      html  css  js  c++  java
  • 洛谷 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,J1000。

    2018.7.25新添数据一组

    蒟蒻博主又回来啦

    图论作业做到自闭,于是来洛谷摸鱼qwq

    答案目测是最小生成树的边权之和加上一个单价,想了想似乎超过单价的边权就不需要了,于是把这些边删掉,分别求每一个连通块的最小生成树,最后加上连通块个数*单价。

    #include<iostream>
    using namespace std;
    const int N = 1005;
    int n,m,ans,v[N][N],dis[N];
    bool b[N];
    int main()
    {
        cin>>m>>n;
        for(int i=1;i<=n;++i)
            for(int j=1;j<=n;j++)
            {
                cin>>v[i][j];
                if(v[i][j]>m)
                    v[i][j] = 0;
            }
        while(1)
        {
            int u = -1;
            for(int i=1;i<=n;i++)
                if(!b[i])
                    u = i;
            if(u == -1)
                break;
            b[u] = 1;
            ans += m;
            for(int i=1;i<= n;++i)
                dis[i] = v[u][i];
            dis[u] = -1;
            while(1)
            {
                int vv = -1,mn = 1e9+7;
                bool flg = 0;
                for(int i=1 ;i <= n;++i)
                    if(dis[i] > 0 && dis[i] < mn)
                    {
                        mn = dis[i];
                        vv = i;
                        flg = 1;
                    }
                if(!flg)
                    break;
                ans += mn;
                b[vv] = 1;
                dis[vv] = -1;
                for(int i=1;i<=n;++i)
                    if(dis[i]>=0 && v[vv][i] && (dis[i] > v[vv][i] || dis[i] == 0))
                        dis[i] = v[vv][i];
            }
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code
  • 相关阅读:
    Python什么是二次开发的意义?python在.net项目采用
    斐波那契数
    Java 兑换ObjectC代码
    第18本:《整理的艺术》
    第16本:《视觉繁美:信息可视化方法与案例解析》
    第14本:《李鸿章传》
    第10本:《设计心理学》
    第17本:《代码的未来》
    第15本:《视不可当----信息图与可视化传播》
    第13本:《富爸爸,穷爸爸》
  • 原文地址:https://www.cnblogs.com/fantasquex/p/10887186.html
Copyright © 2011-2022 走看看