【CERC2016】爵士之旅 Jazz Journey(贪心)
只用考虑2个点之间的情况
相当于就是一个序列
可以删去,每种价格不一样
求最小价格
设为
然后就先是或者,把便宜的那种所有都先删去
然后再把剩下的单个的删去即可
#include<bits/stdc++.h>
#include<tr1/unordered_map>
using namespace std;
using namespace tr1;
const int RLEN=1<<20|1;
inline char gc(){
static char ibuf[RLEN],*ib,*ob;
(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob)?EOF:*ib++;
}
#define gc getchar
inline int read(){
char ch=gc();
int res=0,f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
#define ll long long
#define re register
#define pb push_back
#define cs const
#define pii pair<int,int>
#define fi first
#define se second
cs int N=300005;
cs int bas=192617;
vector<pii> p;
tr1::unordered_map<ll,ll> mp;
pii e[N];
int vis[N],d[N],s[N],a[N];
int n,m,q;
ll ans;
vector<int> last[N];
inline ll has(int a,int b,int c){
return 1ll*a*bas*bas+1ll*b*bas+c;
}
inline ll query(int a,int b,int c){
if(mp.count(has(a,b,c)))return mp[has(a,b,c)];return 2e9;
}
int main(){
n=read(),m=read();
for(int i=1;i<=m;i++)a[i]=read();
q=read();
for(int i=1;i<=q;i++){
int u=read(),v=read();
char ch=gc();
while(ch!='O'&&ch!='R')ch=gc();
ll now=has(u,v,ch=='R');
ll c=read();
if(mp.count(now))mp[now]=min(mp[now],c);
else mp[now]=c;
}
for(int i=1;i<m;i++){
e[i]=pii(a[i],a[i+1]);
if(e[i].fi>e[i].se)swap(e[i].fi,e[i].se),d[i]=1;
p.pb(e[i]);
}
sort(p.begin(),p.end()),p.erase(unique(p.begin(),p.end()),p.end());
for(int i=1;i<m;i++)
last[lower_bound(p.begin(),p.end(),e[i])-p.begin()].pb(d[i]);
for(int i=0;i<p.size();i++){
int u=p[i].fi,v=p[i].se,a=0,b=1,cnt,ab,ba;
ll A=query(u,v,0),B=query(v,u,0),AB=query(u,v,1),BA=query(v,u,1);
A=min(A,AB),B=min(B,BA),AB=min(AB,A+B),BA=min(BA,A+B);
if(AB>BA) swap(a,b),swap(AB,BA);
memset(vis,0,sizeof(int)*(last[i].size())),cnt=0;
for(int j=0;j<last[i].size();j++){
if(last[i][j]==a)s[++cnt]=j;
else if(cnt)ans+=AB,vis[s[cnt]]=vis[j]=1,cnt--;
}
cnt=0;
for(int j=0;j<last[i].size();j++){
if(vis[j])continue;
if(last[i][j]==b)s[++cnt]=j;
else if(cnt)ans+=BA,vis[s[cnt]]=vis[j]=1,cnt--;
}
for(int j=0;j<last[i].size();j++)if(!vis[j])ans+=(last[i][j]==0?A:B);
}
cout<<ans;
}