http://acm.timus.ru/problem.aspx?space=1&num=1741

题目大意:

主人翁需要升级客户端 现在的版本是  1  Licensed

想以最快速度升级到版本 n

m 个 upgrade programs

每一个都有属性 x  y  d  s

表示可以将版本x 升级到版本 y  d为它的大小 越小下载越快  s为类型 有 Licensed     Cracked    Pirated三种

升级是有限制的 从x开始升级必须 当前版本就是x    

一旦被Pirated升级后 无论再用什么类型升级 都还是 Pirated

Licensed不可以在Pirated版本上升级

要求所以用到的软件的d的和 最小

存在达不到的情况

ans0[i]表示升级到版本i 且类型为Pirated的最小时间

ans1[i]表示升级到版本i 且类型为非Pirated的最小时间

将m个upgrade programs 按 x 进行排序后 对ans 进行更新 最后取两种情况的最忧答案进行比较

代码及其注释:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<queue>
#include<stack>
#include<cmath>
#define LL long long

using namespace std;
const int N=10005;
const LL INF=0xffffffffffff;//最大
LL ans0[N];//升级到版本i 且类型为Pirated 最小时间
LL ans1[N];//升级到版本i 且类型为非Pirated 的最小时间
struct node
{
    int x,y,d,k;
}program[N];//升级程序
bool cmp(node a,node b)
{
    return a.x<b.x;
}
LL Fmin(LL a,LL b)
{
    if(a<b)
    return a;
    return b;
}
void dp(int m)
{
    ans1[1]=0;//初始化
    for(int i=0;i<m;++i)
    {
        int x=program[i].x;
        int y=program[i].y;
        int k=program[i].k;
        int d=program[i].d;
        if(ans0[x]<INF&&k!=2)//更新 k!=2 是因为Licensed 不能在Pirated上更新
        {
            ans0[y]=Fmin(ans0[y],ans0[x]+d);
        }
        if(ans1[x]<INF)
        {
            if(k==0)//根据版本更新
            {ans0[y]=Fmin(ans0[y],ans1[x]+d);}
            else
            {ans1[y]=Fmin(ans1[y],ans1[x]+d);}
        }
    }
}
int main()
{
//   freopen("data","r",stdin);
    int n,m;
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        char stemp[10];
        for(int i=1;i<=n;++i)
        ans0[i]=ans1[i]=INF;
        for(int i=0;i<m;++i)
        {
            scanf("%d %d %d %s",&program[i].x,&program[i].y,&program[i].d,stemp);
            if(stemp[0]=='L')//将不同类型用 数字表示
            program[i].k=2;
            else if(stemp[0]=='C')
            program[i].k=1;
            else
            program[i].k=0;
        }
        sort(program,program+m,cmp);//按x排序
        dp(m);
        LL ans=Fmin(ans0[n],ans1[n]);//求最优
        if(ans==INF)
        printf("Offline\n");
        else
        {
            printf("Online\n");
            cout<<ans<<endl;
        }
    }
    return 0;
}

  

posted on 2012-08-22 19:07  夜->  阅读(196)  评论(0编辑  收藏  举报