题解 P6005 [USACO20JAN]Time is Mooney G

Posted dannyxu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解 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;//输出
}

以上是关于题解 P6005 [USACO20JAN]Time is Mooney G的主要内容,如果未能解决你的问题,请参考以下文章

题解 P3605 [USACO17JAN]Promotion Counting晋升者计数

P3116 [USACO15JAN]会议时间Meeting Time

洛谷P3116 [USACO15JAN]约会时间Meeting Time

USACO08JAN Telephone Lines 题解

洛谷 P2978 [USACO10JAN]下午茶时间Tea Time

BZOJ-3890: [Usaco2015 Jan]Meeting Time (背包DP)