题目传送门
题目大意:
看题面吧。
思考过程&具体做法:
先缩点,然后从市中心所在的新点开始做dp,最后对有酒吧的新点统计答案。
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn=5e5+1000;
struct stu
{
int to,next;
}road[maxn],newroad[maxn]; int first[maxn],cnt=0,last[maxn],cnt1=0;
struct lily
{
int x,y;
}len[maxn];
int n,m,top,colnum,s,p,ans;
int dfn[maxn],low[maxn],sta[maxn],book[maxn],mark[maxn],sum[maxn],col[maxn],pub[maxn],money[maxn],dp[maxn];
queue <int> q;
void addedge(int x,int y)
{
road[++cnt].to=y;
road[cnt].next=first[x];
first[x]=cnt;
}
void tarjan(int now)
{
dfn[now]=low[now]=++cnt;
sta[++top]=now;
book[now]=1;
for(int i=first[now];i;i=road[i].next)
{
int to=road[i].to;
if(!dfn[to]) { tarjan(to);low[now]=min(low[now],low[to]); }
else if(book[to]) low[now]=min(low[now],dfn[to]);
}
if(low[now]==dfn[now])
{
colnum++;
while(top>=1&&sta[top]!=now)
{
if(pub[sta[top]]) mark[colnum]=1;
sum[colnum]+=money[sta[top]];
book[sta[top]]=0;
col[sta[top]]=colnum;
top--;
}
if(pub[sta[top]]) mark[colnum]=1;
sum[colnum]+=money[sta[top]];
book[sta[top]]=0;
col[sta[top]]=colnum;
top--;
}
}
bool cmp1(lily t1,lily t2)
{
return t1.x==t2.x?t1.y<t2.y:t1.x<t2.x;
}
void add_newedge(int x,int y)
{
newroad[++cnt1].to=y;
newroad[cnt1].next=last[x];
last[x]=cnt1;
}
int main()
{
// freopen("45.in","r",stdin);
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
addedge(x,y);
len[i].x=x,len[i].y=y;
}
for(int i=1;i<=n;i++) scanf("%d",&money[i]);
scanf("%d%d",&s,&p);
for(int i=1;i<=p;i++)
{
int x;
scanf("%d",&x);
pub[x]=1;
}
cnt=0;
// cout<<1<<endl;
for(int i=1;i<=n;i++)
if(!dfn[i])
{
tarjan(i);
}
// cout<<1<<endl;
for(int i=1;i<=m;i++)
{
len[i].x=col[len[i].x];
len[i].y=col[len[i].y];
}
sort(len+1,len+1+m,cmp1);
for(int i=1;i<=m;i++)
{
int x=len[i].x,y=len[i].y;
if(x==y||(x==len[i-1].x&&y==len[i-1].y)) continue;
add_newedge(x,y);
}
memset(book,0,sizeof(book));
q.push(col[s]);
dp[col[s]]=sum[col[s]];
book[col[s]]=1;
while(!q.empty())
{
int now=q.front();q.pop();book[now]=0;
for(int i=last[now];i;i=newroad[i].next)
{
int to=newroad[i].to;
dp[to]=max(dp[to],dp[now]+sum[to]);
if(!book[to]) { book[to]=1; q.push(to); }
}
}
for(int i=1;i<=colnum;i++)
if(mark[i]) ans=max(ans,dp[i]);
printf("%d\n",ans);
return 0;
}