首页 > 其他分享 >AcWing 903. 昂贵的聘礼 (超级源点 + 等级限制 + 抽象建图

AcWing 903. 昂贵的聘礼 (超级源点 + 等级限制 + 抽象建图

时间:2023-11-26 14:33:05浏览次数:42  
标签:903 level int 源点 建图 static 100 等级

package 算法提高课;

import java.util.Arrays;
import java.util.Scanner;

public class acw903 {
    static int m, n;
    static int[] dis, level;
    static boolean[] st;
    static int[][] g;

    /*
    * 思路 : 首先用到了虚拟源点, 加入了等级限制
    *       先不说等级限制的前提下讨论题目 => 单纯的虚拟源点问题了就是, 因为不知道从哪一个物品开始买是最好的, 所以我们让下标为0的点作为源点, 让其连上别的所有的节点, 边权就是直接购买该点的花费p
    *                                   接着问题就变成了简单的单源最短路问题
    *       在刚刚的基础上讨论等级限制 => 其实非常简单粗暴, 我们注意数据范围, N只有100, M >= 1, 所以我们最坏也只有100个区间, 朴素dij的时间复杂度是 O(n^2) 所以整体算下来时间复杂度是100 * 100 * 100 = 1e6
    *                                所以我们只需要把所有包含第1个物品 (酋长的承诺是物品1, 我们的目的就是买这个物品, 且酋长的等级不一定最高) 的等级区间 (如何求只符合等级区间的点集的最小花费, 见下面代码) 的最小花费都求出来, 然后取一个min就好了
    *
    *       (ps : dij不需要考虑自环的问题, 因为 d[t] <= d[t] + g[t][t] 是严格成立的)
    * */

    private static void init() {
        g = new int[n + 10][n + 10];
        level = new int[n + 10];
        dis = new int[n + 10];
        st = new boolean[n + 10];

        for (int i = 1; i <= n; i ++ ) Arrays.fill(g[i], 0x3f3f3f3f);
    }

    // down表示可交易区间的
    private static int dij(int down, int up) {
        Arrays.fill(dis, 0x3f3f3f3f);
        Arrays.fill(st, false);
        // 每次求解之前记得初始化
        dis[0] = 0; // 从源点开始搜

        // dij板子
        for (int i = 1; i <= n + 1; i ++ ) {
            int t = -1;
            for (int j = 0; j <= n; j ++ )
                if (!st[j] && (t == -1 || dis[t] > dis[j])) t = j;

            st[t] = true;
            for (int j = 0; j <= n; j ++ )
                if (level[j] >= down && level[j] <= up)
                    dis[j] = Math.min(dis[j], dis[t] + g[t][j]);
            // 注意上面, 只更新符合等级区间要求的点
        }

        return dis[1]; // 返回结果
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        m = sc.nextInt(); n = sc.nextInt();
        init(); // 初始化
        // 我们把0认为是虚拟源点, g[0][i]代表直接购买i这个物品的边
        for (int i = 1; i <= n; i ++ ) {
            int p = sc.nextInt(), l = sc.nextInt(), x = sc.nextInt();
            g[0][i] = p; // 如上
            level[i] = l;
            // g[t][j]代表t这个物品作为替代优惠购买j这个物品的花费
            while (x -- > 0) {
                int t = sc.nextInt(), v = sc.nextInt();
                g[t][i] = Math.min(g[t][i], v); // 重边只存一个最小的
            }
        }

        int ans = 0x3f3f3f3f;
        for (int i = level[1] - m; i <= level[1]; i ++ ) ans = Math.min(ans, dij(i, i + m)); // 把所有包含level[1]的区间全搜一遍, 这样时间复杂度最多是100 * (100 * 100) = 1e6
        // 注意酋长的等级不一定是最高的
        System.out.println(ans);
    }
}

标签:903,level,int,源点,建图,static,100,等级
From: https://www.cnblogs.com/llihaotian666/p/17857173.html

相关文章

  • 线段树优化建图
    CF786B题意:定义\((u,v,w)\)表示\(u\)向\(v\)连了边权为\(w\)的边。有三种连边操作\((u,v,w)\)\(\foralli\in[l,r],(u,i,w)\)\(\foralli\in[l,r],(i,u,w)\)求最短路。暴力加边是\(O(nm)\)的,考虑优化。可以把图建到线段树上,线段树每个结点向左右儿子连\(w......
  • Codeforces Round 903 (Div. 3)
    CodeforcesRound903(Div.3)A.Don'tTrytoCount大概题意给你两个字符串a,b。a串可进行的操作为将整个a串复制到之前的a串后面(直接用a+a即可),然后看操作多少次可以让b串变为a串的子串如果不能就输出-1。#include<iostream>usingnamespacestd;stringa,b;voidsolve()......
  • Codeforces Round 903 (Div. 3) ABCDE
    CodeforcesRound903(Div.3)ABCDEA.Don'tTrytoCount题意:复制\(s\)串若干遍,是否能在\(s\)串中找到\(t\)串。思路:直接暴力,注意不要超限,会MLE//AConemoretimes//nndbk#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;constintmod=1e9+......
  • 2008秋季-计算机软件基础-0903课堂用例(1)
    #include<stdio.h>voidupdate(intxiabiao,intb[],intxinshu);voidcharu(intweizhi,intb[],intcharushu,intshuzuchang);voidshanchu(intweizhi,intb[],int*changdu);voidshuchu(intaa[],intbiaochang);voidchazhao(int......
  • 【算法题】2903. 找出满足差值条件的下标 I
    题目:给你一个下标从0开始、长度为n的整数数组nums,以及整数indexDifference和整数valueDifference。你的任务是从范围[0,n-1]内找出2个满足下述所有条件的下标i和j:abs(i-j)>=indexDifference且abs(nums[i]-nums[j])>=valueDifference返回整数数组a......
  • 题解 CF903G【Yet Another Maxflow Problem】
    加边\(A_n\stackrel{0}{\to}A_{n+1}\),\(B_0\stackrel{0}{\to}B_1\)。称形如\(A_i\toA_{i+1}\)的边为左部边,形如\(B_j\toB_{j+1}\)的边为右部边,形如\(A_i\toB_j\)的边为中间边。根据最大流最小割定理,将最大流问题转化为最小割问题求解。显然,至少存在一组最小割,包含恰好......
  • antd G6中建立图表时,让赋值速度慢于建图速度的一个解决方法
    通过异步加载的方式将数据加载和图表建立过程分离,一个简单的例子:import{Chart}from'@antv/g6'//创建一个空的图表容器constcontainer=document.getElementById('chart-container');constchart=newChart({container,//其他配置项...});//异步加......
  • P6378 [PA2010] Riddle-2sat优化建图
    P6378[PA2010]Riddle-2sat优化建图\(n\)个点\(m\)条边的无向图被分成\(k\)个部分。每个部分包含一些点。请选择一些关键点,使得每个部分恰有一个关键点,且每条边至少有一个端点是关键点。\(1\leqn,m\leq10^6\)边的限制用\(n\)个变量\(x_1\dotsx_n\),其中\(x_i\)......
  • Codeforces Round 903 (Div. 3)
    [比赛链接]A.Don'tTrytoCount直接用string的可加性,每次s+=s相当于翻倍了,因为\(nm<=25\)所以最多翻倍5次。判断什么的直接模拟就行。#include<iostream>#include<algorithm>#include<cmath>#include<cstdio>#include<cstring>#include<cstdlib>#inclu......
  • Codeforces Round 903 (Div. 3) F. Minimum Maximum Distance(图论)
    CodeforcesRound903(Div.3)F.MinimumMaximumDistance思路对标记点更新fg,从0开始进行bfs,更新d1为所有点到0的距离获得到0最远的标记点L,从L开始bfs,更新d2为所有点到L的距离获得距离L最远的标记点R,从R开始bfs,更新d3为所有点到R的距离遍历所有点,这个点与标记点的最大距......