• GYM101635E Ingredients


    题目链接:https://vjudge.net/problem/Gym-101635E

    题目大意:

      给定一个有 (N) 条边的有向无环图(有多个起点),每条边都有其费用和收益,现要从一个或多个起点出发,以某一个或多个点为终点(一个点不能多次作为终点;如果有多个方案能到达同一个点,则选择总费用最少的),问在使得总费用不超过 (B) 的大前提下,能得到的最大收益(如果有多个得到最大收益的方法,则选择使得费用最少的)。输出最大收益及其对应的总费用。

      (建议仔细地读一下 (Important Notes))

    知识点:  DP、最短路

    解题思路:

      先用 (Dijkstra) 跑出从各个起点到各个点的最小费用及其对应的收益(如果有多个费用最小的方案,则选择收益最大的那个),再用 (dp) 计算出在各个总费用下所能得到的最大收益。

    AC代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxm = 1000000+5, maxn = 10000+5, inf=0x3f3f3f3f;
     4 
     5 struct Edge{
     6     int to,nxt,cost,prestige;
     7 }edge[maxm];
     8 int head[maxm],tot;
     9 void init(){
    10     memset(head,-1,sizeof(head));
    11     tot=0;
    12 }
    13 void addedge(int u,int v,int cost,int pres){
    14     edge[tot].to=v;
    15     edge[tot].nxt=head[u];
    16     edge[tot].prestige=pres;
    17     edge[tot].cost=cost;
    18     head[u]=tot++;
    19 }
    20 
    21 int min_cost[maxn],max_pres[maxn];
    22 bool noroot[maxn];
    23 map<string,int> ind;
    24 
    25 void dijkstra(int s){
    26     queue<int> que;
    27     que.push(s);
    28     min_cost[s]=max_pres[s]=0;
    29     while(!que.empty()){
    30         int v=que.front();
    31         que.pop();
    32         for(int i=head[v];i!=-1;i=edge[i].nxt){
    33             int to=edge[i].to;
    34             if(min_cost[to]>min_cost[v]+edge[i].cost){
    35                 min_cost[to]=min_cost[v]+edge[i].cost;
    36                 max_pres[to]=max_pres[v]+edge[i].prestige;
    37                 que.push(to);
    38             }
    39             else if(min_cost[to]==min_cost[v]+edge[i].cost&&max_pres[to]<max_pres[v]+edge[i].prestige){
    40                 max_pres[to]=max_pres[v]+edge[i].prestige;
    41                 que.push(to);
    42             }
    43         }
    44     }
    45 }
    46 int dp[maxn];
    47 int main(){
    48     std::ios::sync_with_stdio(false);   //如果没有加速输入输出的话会T
    49     int B,N,cos,pre,u,v;
    50     int cnt=1;
    51     string to,from,tmp;
    52     cin>>B>>N;
    53     init();
    54     for(int i=0;i<N;i++){
    55         cin>>to>>from>>tmp>>cos>>pre;
    56         if(!ind[to])
    57             ind[to]=cnt++;
    58         v=ind[to];
    59         if(!ind[from])
    60             ind[from]=cnt++;
    61         u=ind[from];
    62         addedge(u,v,cos,pre);
    63         noroot[v]=true;
    64     }
    65     for(int i=1;i<cnt;i++)
    66         min_cost[i]=inf,max_pres[i]=0;
    67     for(int i=1;i<cnt;i++){
    68         if(!noroot[i])
    69             dijkstra(i);
    70     }
    71     dp[0]=0;
    72     for(int i=1;i<cnt;i++){
    73         for(int j=B;j>=min_cost[i];j--)
    74             dp[j]=max(dp[j],dp[j-min_cost[i]]+max_pres[i]);
    75     }
    76     int ans1=0,ans2=0;
    77     for(int i=0;i<=B;i++){
    78         if(dp[i]>ans1)
    79             ans1=dp[i],ans2=i;
    80     }
    81     cout<<ans1<<endl;
    82     cout<<ans2<<endl;
    83 
    84     return 0;
    85 }
    “这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
  • 相关阅读:
    结对编程项目---四则运算
    作业三(代码规范、代码复审、PSP)
    作业2(源程序管理软件与项目管理软件)
    学习总结
    作业1
    寒假超市实习
    《软件工程》课程总结
    结对编程项目---四则运算
    作业三: 代码规范、代码复审、PSP
    作业二(2)目前流行的源程序版本管理软件和项目管理软件都有哪些,各有什么优缺点?
  • 原文地址:https://www.cnblogs.com/Blogggggg/p/8595859.html
Copyright © 2020-2023  润新知