Description

Farmer John's family pitches in with the chores during milking, doing all the chores as quickly as possible. At FJ's house, some chores cannot be started until others have been completed, e.g., it is impossible to wash the cows until they are in the stalls. 



Farmer John has a list of N (3 <= N <= 10,000) chores that must be completed. Each chore requires an integer time (1 <= length of time <= 100) to complete and there may be other chores that must be completed before this chore is started. We will call these
prerequisite chores. At least one chore has no prerequisite: the very first one, number 1. Farmer John's list of chores is nicely ordered, and chore K (K > 1) can have only chores 1,.K-1 as prerequisites. Write a program that reads a list of chores from 1
to N with associated times and all perquisite chores. Now calculate the shortest time it will take to complete all N chores. Of course, chores that do not depend on each other can be performed simultaneously.

Input

* Line 1: One integer, N 



* Lines 2..N+1: N lines, each with several space-separated integers. Line 2 contains chore 1; line 3 contains chore 2, and so on. Each line contains the length of time to complete the chore, the number of the prerequisites, Pi, (0 <= Pi <= 100), and the Pi
prerequisites (range 1..N, of course). 

Output

A single line with an integer which is the least amount of time required to perform all the chores. 

       原题很简单,就是给定N个任务的时间和每个任务的前驱,求最短完成时间。
       初步研究,此题可以用最长路或是拓扑图来求解。

        vijos上有一道“休息中的小呆”,原理和此类似,然而那儿N<=100,N^3也绰绰有余,我就用floyd算法求出最长路并记录。然而现在的N<=10000,就连N^2也很危险。

        第一次,我打算也是用最长路求解。咨询过鼎神,目前只有SPFA可以有效处理最长路问题。方法就是把每条边的权值取相反数并做一遍最短路,答案再取相反数。因为N有10000而边数不知道,只好开一个边表记录。

代码一(SPFA最长路+边表优化)
#include<stdio.h>
#include<cstring>
using namespace std;
const long maxn=10001;const long INF=1;
bool flag[maxn];long cnt,i,n,j,xx,time,y,h,t,go,now,ans,tong;
long dis[maxn],begin[maxn],end[maxn],x[200*maxn];
struct arr{long l,r,s,next;}a[200*maxn];
void make_up(long l,long r,long v)
{
  a[++cnt].l=l;a[cnt].r=r;a[cnt].s=-v;a[cnt].next=-1;
  if (begin[l]==0) {begin[l]=cnt;end[l]=cnt;}
  else {a[end[l]].next=cnt;end[l]=cnt;}
}
int main()
{
  //freopen("chores.in","r",stdin);freopen("chores.out","w",stdout);
  scanf("%ld",&n);
  for (i=1;i<=n;i++)
  {
    scanf("%ld",&time);
    scanf("%ld",&xx);
    for (j=1;j<=xx;j++)
    {
      scanf("%ld",&y);
      make_up(y,i,time);
    }
    if (xx==0) make_up(0,i,time);
  }
  memset(flag,0,sizeof(flag));memset(dis,INF,sizeof(dis));
  h=0;t=1;x[1]=0;dis[0]=0;flag[0]=true;
  while (h<t)
  {
     now=x[++h];if (begin[now]==0) continue;i=begin[now];
     while (true)
     {
       go=a[i].r;
       if (dis[now]+a[i].s<dis[go])
       {
         dis[go]=dis[now]+a[i].s;
         if (!flag[go])
         {
           flag[go]=true;
           x[++t]=go;
         }
       }
       if (a[i].next==-1) break;i=a[i].next;
     }
     flag[now]=false;
  }
  for (i=1;i<=n;i++)
    if (-dis[i]>ans) ans=-dis[i];

  printf("%ld",ans);
  //scanf("%ld",&n);
  return 0;
}

然而交了之后一直TLE,自己下了个数据,发现最后一个点大概要13s左右!想不到在稠密图里,SPFA的效率又如此之低!(边表的常数又很大)无论怎么优化都不行!

       
       最后只能请教互联网了,没想到,其他大牛的代码如此简单!他们用了近似DP的算法!

代码二(据网上思路改编代码)
#include<stdio.h>
#include<cstring>
using namespace std;
long f[10001],n,i,j,max,ans,xx,y;
int main()
{
  //freopen("chores.in","r",stdin);freopen("chores.out","w",stdout);
  scanf("%ld",&n);
  for (i=1;i<=n;i++)
  {
    scanf("%ld",&f[i]);
    scanf("%ld",&xx);max=0;
    for (j=1;j<=xx;j++)
    {
      scanf("%ld",&y);
      if (f[y]>max) max=f[y];
    }
    f[i]+=max;
    if (f[i]>ans) ans=f[i];
  }
  printf("%ld",ans);
  //scanf("%ld",&n);
  return 0;
}

然而仔细一想,我发现他们只是钻了一个数据的漏洞——刚好数据的前后关系是由小到大的。思考了很长时间,我研究出了一个更加高级的算法——记忆化深搜+边表优化!


代码三(最终AC的代码)
#include<stdio.h>
#include<cstring>
using namespace std;
const long maxn=10001;const long INF=1;
long time[maxn],dp[maxn],begin[maxn],end[maxn],cnt,j,n,i,x,y,ans;
struct arr{long l,r,next;}a[200*maxn];
void make_up(long l,long r)
{
  a[++cnt].l=l;a[cnt].r=r;a[cnt].next=-1;
  if (begin[l]==0) {begin[l]=cnt;end[l]=cnt;}
  else {a[end[l]].next=cnt;end[l]=cnt;}
}
long go(long k)
{
  if (dp[k]>0) return dp[k];
  long now=begin[k];
  while (now>0)
  {
    long temp=go(a[now].r);
    dp[k]=(temp>dp[k])?temp:dp[k];
    now=a[now].next;
  }
  dp[k]+=time[k];
  return dp[k];
}
int main()
{
  //freopen("chores.in","r",stdin);freopen("chores.out","w",stdout);
  scanf("%ld",&n);
  for (i=1;i<=n;i++)
  {
    scanf("%ld",&time[i]);
    scanf("%ld",&x);
    for (j=1;j<=x;j++)
    {
      scanf("%ld",&y);make_up(i,y);
    }
    if (x==0) dp[i]=time[i];
  }
  for (i=1;i<=n;i++)
  {
    long temp=go(i);
    ans=(temp>ans)?temp:ans;
  }
  printf("%ld",ans);
  //scanf("%ld",&n);
  return 0;
}

希望众神牛看到后能够留言指导!


usaco 2002 月赛 Chores 题解的更多相关文章

  1. usaco 2002 月赛 Fiber Communications 题解

    Description Farmer John wants to connect his N (1 <= N <= 1,000) barns (numbered 1..N) with a ...

  2. POJ1944 Fiber Communications (USACO 2002 February)

    Fiber Communications 总时间限制:  1000ms 内存限制:  65536kB 描述 Farmer John wants to connect his N (1 <= N ...

  3. csu-2018年11月月赛Round2-div1题解

    csu-2018年11月月赛Round2-div1题解 A(2191):Wells的积木游戏 Description Wells有一堆N个积木,标号1~N,每个标号只出现一次 由于Wells是手残党, ...

  4. csu-2018年11月月赛Round2-div2题解

    csu-2018年11月月赛Round2-div2题解 A(2193):昆虫繁殖 Description 科学家在热带森林中发现了一种特殊的昆虫,这种昆虫的繁殖能力很强.每对成虫过x个月产y对卵,每对 ...

  5. usaco 2008 月赛 lites 开关灯 题解

      题目:     Farmer John尝试通过和奶牛们玩益智玩具来保持他的奶牛们思维敏捷. 其中一个大型玩具是 牛栏中的灯. N (2 <= N <= 100,000) 头奶牛中的每一 ...

  6. USACO全部月赛及GateWay数据

    月赛: 以07年open为例,网站如下 http://contest.usaco.org/OPEN07 其他的格式是http://contest.usaco.org/月份(月份的英文前三位,比如1月是 ...

  7. USACO Section 1.3 题解 (洛谷OJ P1209 P1444 P3650 P2693)

    usaco ch1.4 sort(d , d + c, [](int a, int b) -> bool { return a > b; }); 生成与过滤 generator&& ...

  8. 洛谷10月月赛II题解

    [咻咻咻] (https://www.luogu.org/contestnew/show/11616) 令人窒息的洛谷月赛,即将参加NOIp的我竟然只会一道题(也可以说一道也不会),最终145的我只能 ...

  9. BZOJ Lydsy5月月赛 ADG题解

    题目链接 BZOJ5月月赛 题解 好弱啊QAQ只写出三题 A 判断多干个数乘积是否是某个数的倍数有很多方法,比较常用的是取模,但这里并不适用,因为模数不定 会发现数都比较小,所以我们可以考虑分解质因子 ...

随机推荐

  1. Ultimus BPM 零售和快消品行业应用解决方案

    Ultimus BPM 零售和快消品行业应用解决方案 行业应用需求 中国零售及快消品行业正在经历深刻变化.经济下滑,消费回落,行业危机继续发酵:人员工资.房租费用进一步上涨,成本高涨成为不能承受之重: ...

  2. iOS学习之应用之间的操作(转发)

    首先要说的是每一个APP都可以设置一个自己独有的URL,APP应用之间的操作就是通过这个URL来实现的! 1.如何配置自己应用的URL? 关于自己的URL,作为资深的程序猿都会想到 Info.plis ...

  3. 我和 flow.ci 的第一次亲密接触

    编者按:本文转载自 flow.ci 用户 @君赏 的实践分享,原文链接这里. 这不是第一次听说 flow.ci ,记得当时 fir.im 新出这个服务的时候,我也是心情十分激动的去尝试,结果是只支持安 ...

  4. win10下装mysql-5.7.18-winx64

    步骤1 官网下载地址:https://dev.mysql.com/downloads/mysql/ 选择手动安装版: 解压到D盘mysql文件夹下: 比以往的版本里缺少了两个.ini文件,直接copy ...

  5. Ace Admin 使用教程

    (原) 公司项目要换框架,然后丢了一套国外的给我,ace admin,本想着拿来改改,翻翻百度就能用的,可它是国外的啊,国内普及率又不高,没办法,硬着头皮一点点啃英文文档吧. File(文件) 简介: ...

  6. Java IO流之【缓冲流和文件流复制文件对比】

    与文件流相比,缓冲流复制文件更快 代码: package Homework; import java.io.BufferedOutputStream; import java.io.File; imp ...

  7. 论文笔记 Spatial contrasting for deep unsupervised learning

    在我们设计无监督学习模型时,应尽量做到 网络结构与有监督模型兼容 有效利用有监督模型的基本模块,如dropout.relu等 无监督学习的目标是为有监督模型提供初始化的参数,理想情况是"这些 ...

  8. 基于NopCommerce的开发框架——缓存、网站设置、系统日志、用户操作日志

    最近忙于学车,抽时间将Nop的一些公用模块添加进来,反应的一些小问题也做了修复.另外有园友指出Nop内存消耗大,作为一个开源电商项目,性能方面不是该团队首要考虑的,开发容易,稳定,代码结构清晰简洁也是 ...

  9. [Leetcode] Binary search, DP--300. Longest Increasing Subsequence

    Given an unsorted array of integers, find the length of longest increasing subsequence. For example, ...

  10. React + Redux + express+ antd 架构的认识

    在过去的两周里,我使用这套技术栈进行项目页面的开发.下面是我个人的对于项目的一些看法: 首先:是项目的调试,我深表压力很大,项目是使用fibber去抓包调试的,也不知道我们项目的负责人,怎么能的我在每 ...