P3077 [USACO13FEB] Route Design G
思路
DP。
首先将每条边按左端点排序,若左端点相同则按右端点排序。这保证了状态转移时路径不交叉。
设
设
对于每一条边,设其左右两端分别为
用更新后的
在每个状态更新前已经考虑了所有前驱状态,因此最终答案必然最优。
时间复杂度:将边排序
Code
#include<bits/stdc++.h>
#define int long long
#define maxn 40010
#define maxe 100010
using namespace std;
int n,m,r,a[maxn],b[maxn],f[maxn],g[maxn],ans;
struct edge{
int u,v;
bool operator<(const edge &tt)const{return (u^tt.u)?(u<tt.u):(v<tt.v);}
}e[maxe];
inline int read(){
int ret=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')ret=ret*10+(ch&15),ch=getchar();
return ret*f;
}
signed main(){
n=read(),m=read(),r=read();
for(int i=1;i<=n;i++)a[i]=f[i]=read(),ans=max(ans,a[i]);
for(int i=1;i<=m;i++)b[i]=g[i]=read(),ans=max(ans,b[i]);
for(int i=1;i<=r;i++)e[i].u=read(),e[i].v=read();
sort(e+1,e+r+1);
for(int i=1;i<=r;i++){
int t1=f[e[i].u],t2=g[e[i].v];
f[e[i].u]=max(f[e[i].u],t2+a[e[i].u]);
g[e[i].v]=max(g[e[i].v],t1+b[e[i].v]);
ans=max(ans,max(f[e[i].u],g[e[i].v]));
}
printf("%lld\n",ans);
return 0;
}