Timus 1741

令res[i][0]表示升级到i并且是正版的最小消费,res[i][1]表示升级到i并且是盗版的最小消费。

res[i][0]=min(res[i][0],res[k][0]+edge(k,i)) (其中k必须可以升级到i,并且保证升级到i是正版);

res[i][1]=min(res[i][1],res[k][x]+edge(k,i)) (其中res[k][x]表示正版盗版都行,关键保证升级到i是盗版)

简单DP不用再说了,不过就是用到临界表来存储边,减小空间复杂度(姑且这样说)。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define lld __int64
#define MAX 0xffffffffff
struct node
{
    int i,cost,next;
    char state;
}edge[10001];
lld dp[10001][2];
int head[10001],N;
int add(int s,int t,int w,char c)
{
    edge[N].i=t;
    edge[N].cost=w;
    edge[N].state=c;
    edge[N].next=head[s];
    return N++;
}
lld min(lld a,lld b)
{
    return a < b ? a : b;
}
int work(int n,int m)
{
    int i,j,k;
    for(i=1;i<=n;i++) dp[i][0]=dp[i][1]=MAX;
    dp[1][0]=dp[1][1]=0;
    for(i=2;i<=n;i++)
    {
        for(j=head[i];j;j=edge[j].next)
        {
            k=edge[j].i;
            if(dp[k][0]<MAX && (edge[j].state=='L'||edge[j].state=='C'))
            {
                dp[i][0]=min(dp[i][0],dp[k][0]+edge[j].cost);
            }
            if(dp[k][0]<MAX && edge[j].state=='P')
            {
                dp[i][1]=min(dp[i][1],dp[k][0]+edge[j].cost);
            }
            if(dp[k][1]<MAX && (edge[j].state=='C' || edge[j].state=='P'))
            {
                dp[i][1]=min(dp[i][1],dp[k][1]+edge[j].cost);
            }
        }
    }
    return 0;
}
int main()
{
    int i,m,n,s,t,w;
    char str[10];
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        N=1;
        memset(head,0,sizeof(head));
        for(i=0;i<m;i++)
        {
            scanf("%d %d %d %s",&s,&t,&w,str);
            head[t]=add(t,s,w,str[0]);
        }
        work(n,m);
        if(dp[n][0] < MAX || dp[n][1] < MAX)
        {
            printf("Online\n%I64d\n",min(dp[n][0],dp[n][1]));
        }
        else
        {
            printf("Offline\n");
        }
    }
    return 0;
}
posted @ 2012-05-03 21:13  书山有路,学海无涯  阅读(290)  评论(0编辑  收藏  举报