思路:
dp
状态:dp[i][1]表示到第i个版本为正版的最少流量花费
dp[i][0]表示到第i个版本为盗版的最少流量花费
初始状态:dp[1][0]=dp[0][0]=0
目标状态:min(dp[n][0],dp[n][1])
状态转移:见代码,注意如果是cracked版本,如果原来是盗版,转移后还是盗版
代码:
#include<bits/stdc++.h> using namespace std; #define ll long long #define mem(a,b) memset(a,b,sizeof(a)) const int N=1e4+5; const ll INF=0x3f3f3f3f3f3f3f3f; ll dp[N][2]; bool vis[N]; int head[N]; struct edge{ int to,w,f,next; }edge[N]; int cnt=0; void add_edge(int u,int v,int w,int f){ edge[cnt].to=v; edge[cnt].w=w; edge[cnt].f=f; edge[cnt].next=head[u]; head[u]=cnt++; } int main(){ ios::sync_with_stdio(false); cin.tie(0); int n,m,x,y,d,t; string s; cin>>n>>m; mem(head,-1); for(int i=0;i<m;i++){ cin>>x>>y>>d>>s; if(s[0]=='L')t=1; else if(s[0]=='P')t=2; else t=3; add_edge(x,y,d,t); } mem(dp,INF); dp[1][0]=0; dp[1][1]=0; for(int i=1;i<=n;i++){ for(int j=head[i];~j;j=edge[j].next){ if(edge[j].f==1){ dp[edge[j].to][1]=min(dp[edge[j].to][1],dp[i][1]+edge[j].w); } else if(edge[j].f==2){ dp[edge[j].to][0]=min(dp[edge[j].to][0],min(dp[i][0],dp[i][1])+edge[j].w); } else if(edge[j].f==3){ dp[edge[j].to][0]=min(dp[edge[j].to][0],dp[i][0]+edge[j].w); dp[edge[j].to][1]=min(dp[edge[j].to][1],dp[i][1]+edge[j].w); } } } ll ans=min(dp[n][1],dp[n][0]); if(ans==INF)cout<<"Offline"<<endl; else { cout<<"Online"<<endl; cout<<ans<<endl; } return 0; }