DP
只存在一个或零个景点的公司可以不需要考虑,只需要考虑有多个景点的公司就可以了,也只需要存储这类公司的状态。
#include<iostream>
#include<vector>
#include<string.h>
using namespace std;
long long n;
vector<long long> g[8000];
long long c[8000],w[8000],t[8000],cn[8000],ss[8000],id[8000],ll[8000][8000];
long long ct(long long x)
{
long long sum=0;
for(int i=1; i<=n; i++)
{
if(x%2!=0)
sum+=w[ss[i]];
x>>=1;
}
return sum;
}
long long fw(long long x)
{
if(cn[c[x]]>=2)
return 0;
return w[c[x]];
}
int main()
{
long long m,s,cnt=0;
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>c[i];
for(int i=1;i<=n;i++) cin>>w[i];
for(int i=1;i<=m;i++)
{
long long x, y;
cin>>x>>y;
g[x].push_back(y);
}
for(int i=1;i<=n;i++)
cn[c[i]]++;
for(int i=1;i<=n;i++)
if(cn[i]>=2)
ss[++cnt]=i,id[i]=cnt;
for(int i=1;i<=n;i++)
t[i]=fw(i);
memset(ll,-1,sizeof(ll));
if(t[1])
ll[0][1]=t[1];
else
ll[1<<(id[c[1]]-1)][1]=ll[0][1]=0;
s=(1<<cnt);
for(int k=0;k<s;k++)
{
for(int i=1;i<=n;i++)
{
if(ll[k][i]==-1)
continue;
for (int j=0;j<(int)g[i].size();j++)
{
long long y=g[i][j];
if(t[y])
{
ll[k][y]=max(ll[k][y], ll[k][i]+t[y]);
}
else
{
long long tt=(1<<(id[c[y]]-1));
ll[tt|k][y]=max(ll[tt|k][y],ll[k][i]);
}
}
}
}
for(int i=1;i<=n;i++)
{
long long ans=0;
for (int j=0;j<s;j++)
{
if(ll[j][i]!=-1)
ans=max(ans,ll[j][i]+ct(j));
}
cout<<ans<<endl;
}
return 0;
}