zoukankan      html  css  js  c++  java
  • 题解 P6005 【[USACO20JAN]Time is Mooney G】

    抢第一篇题解

    这题的思路其实就是一个非常简单的dijkstra,如果跑到第一个点的数据不能更新的时候就输出

    很多人不知道要跑多少次才停.其实这题因为答案要减去 T*c^2,而每条边的值 <= 1000,稍微推一下就可以发现这个程序最多跑1000次.

    所以,简单暴力的做法就是暴力写1000次dijkstra (01dij或者二维1000*1000都可以).这个方法当然可以优化,但是没有超时谁理他呢

    现在剩下一个小问题(如果没有经过的点,我们不能更新连同他的路).那么怎么办呢?

    摆在眼前的路有两条.第一:到所有点的初始值设成-1跑.如果目前的点的值为-1就证明他没有被经过,所以需要跳过

    第二:做一个vis,记录每次经过并且以前没有经过过的点.这里我用的是queue,记录所有这一次被拿到的点.

    注意不要马上更新,因为如果你马上更新就会出现没有经过的点被更新了

    01的意义就是保证所有点更新的都是之前更新过但这一次没有更新的,保证不会出现一条边被更新很多次的情况

    话不多说,上代码

    #include <iostream>
    #include <algorithm>
    #include <math.h>
    #include <queue>
    using namespace std;
    int dp[1005][2],head[100005],tot = 0,n,m,c, cost[1005],ans=0,vis[1005];
    struct Edge{
      int from, to,next;
    }edge[100005];
    void add(int f,int t){
      edge[++tot].from = f;
      edge[tot].to = t;
      edge[tot].next = head[f];
      head[f] = tot;
    }
    void setIO(string name) {
    	freopen((name+".in").c_str(),"r",stdin);
    	freopen((name+".out").c_str(),"w",stdout);
    	ios_base::sync_with_stdio(0);
    }
    //以上不解释
    void dij(int curr){
      queue<int> q;//记经过的边
      for (int i=1;i<=n;i++){
        if (!vis[i]) continue;//如果没有经过就不跑
        for (int j=head[i];j;j=edge[j].next){
          if (!vis[edge[j].to]) q.push(edge[j].to);//没经过就加进queue待会更新
          dp[edge[j].to][curr%2] = max(dp[edge[j].from][(curr+1)%2]+cost[edge[j].to],dp[edge[j].to][curr%2]);
          //要去的点的值现在的点的值+那个点的权值.
        }
      }
      while(!q.empty()){vis[q.front()] = true;q.pop();}
      //将所有经过的点的vis设成true
      ans = max(ans,(int)(dp[1][curr%2]-c*pow(curr,2)));
      //更新答案
    }
    
    int main(){
      // setIO("time");
      cin >> n >> m >> c;
      for (int i=1;i<=n;i++) cin >> cost[i];
      for (int i=0;i<m;i++){
        int a,b; cin >> a >> b;
        add(a,b);//连边,如果要转化为权值问题只需将权值设为cost[b]就行
      }
      vis[1] = true;//将初始点设为已经过
      for (int i=1;i<1000;i++){
        dij(i);//跑1000次
      }
      cout << ans;//输出
    }
    
    
  • 相关阅读:
    MFC加载图片
    动态数组类
    MFC程序打包方法
    如何在C++中使用动态三维数组
    Ansys热应力计算
    像使用数据库一样使用xml
    过年回家的一点感想
    前后端框架和设计模式
    国外支付PayPal
    可重用的管理后台代码
  • 原文地址:https://www.cnblogs.com/DannyXu/p/12232731.html
Copyright © 2011-2022 走看看