timus 1741. Communication Fiend URAL 解题报告 DP+读题
题目大意:把一个软件从版本1升级到版本n(求最小的花费),现在网上有很多升级软件,分别能从xi升级到yi; 而且这些软件有的能升级正版,有的能升级到盗版……
具体规则是:
Pirated能将原来的正版或者盗版升级到现在的盗版Pirated;
Licensed 能将原来的正版升级到现在的正版Licensed ;
Cracked 能将原来的正版或者盗版升级; (Cracked 是正版) 但是需要注意的是一旦软件被升级到盗版,以后就只能视作盗版,也就说Cracked 虽然是正版的,但是如果从盗版升级过来就视为盗版,从正版升级过来就是为正版! 这是个小坑!
还有就是初始化的时候注意,最开始的版本是正版的
先根据xi排序,xi相同yi升序排列…… 然后转化就好了 dp[i][0/1]表示当前版本是i,0盗版, 1正版…… 最小的花费
注意int超了,需要longlong或者__int64……
总结:dp小水题,注意理解题意……
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=40010;
const int M=40010;
long long dp[N][2];
struct Update
{
int x,y,s;
char ch[10];
}pro[M];
int n,m;
bool cmp(Update u1,Update u2)
{
if(u1.x!=u2.x)return u1.x<u2.x;
return u1.y<u2.y;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;++i)
{
scanf("%d %d %d %s",&pro[i].x,&pro[i].y,&pro[i].s,&pro[i].ch);
}
sort(pro+1,pro+m+1,cmp);
memset(dp,-1,sizeof(dp));
// dp[1][0]=0;
dp[1][1]=0;
for(int i=1;i<=m;++i)
{
if(pro[i].ch[0]=='L')
{
if ( dp[pro[i].x][1]!=-1&& (dp[pro[i].y][1]==-1 || dp[pro[i].y][1]>dp[pro[i].x][1]+pro[i].s ) )
{
dp[pro[i].y][1]=dp[pro[i].x][1]+pro[i].s ;
}
}else if(pro[i].ch[0]=='C')
{
if (dp[pro[i].x][1]!=-1&& (dp[pro[i].y][1]==-1|| dp[pro[i].y][1]>dp[pro[i].x][1]+pro[i].s ) )
{///从合法的转化过来
dp[pro[i].y][1]=dp[pro[i].x][1]+pro[i].s ;
}
if (dp[pro[i].x][0]!=-1&& (dp[pro[i].y][0]==-1|| dp[pro[i].y][0]>dp[pro[i].x][0]+pro[i].s ) )
{///从盗版的转化过来
dp[pro[i].y][0]=dp[pro[i].x][0]+pro[i].s ;
}
}else if(pro[i].ch[0]=='P')
{///当前是不合法的
if (dp[pro[i].x][0]!=-1&& (dp[pro[i].y][0]==-1|| dp[pro[i].y][0]>dp[pro[i].x][0]+pro[i].s ) )
{///从盗版的转化过来
dp[pro[i].y][0]=dp[pro[i].x][0]+pro[i].s ;
}
if (dp[pro[i].x][1]!=-1&& (dp[pro[i].y][0]==-1|| dp[pro[i].y][0]>dp[pro[i].x][1]+pro[i].s ) )
{///从合法的转化过来
dp[pro[i].y][0]=dp[pro[i].x][1]+pro[i].s ;
}
}
}
if(dp[n][0]==-1&&dp[n][1]==-1)
{
cout<<"Offline"<<endl;
}else
{
cout<<"Online"<<endl;
if(dp[n][0]==-1)cout<<dp[n][1]<<endl;
else if(dp[n][1]==-1)cout<<dp[n][0]<<endl;
else cout<<min(dp[n][0],dp[n][1])<<endl;
}
return 0;
}