#include<iostream>
#include<cstring>
#include<cstdio>
#define INF 0x3f3f3f3f
using namespace std;
const int maxv=100010;
const int maxe=1000010;
struct Edge{
int to,next,val;
}edge[maxe];
int cnt,TPOindex;
bool visit[maxv];
int head[maxv],w[maxv],in[maxv],out[maxv],dis[maxv],TPO[maxv];
void init(){
cnt=0;
TPOindex=0;
memset(head,-1,sizeof head);
memset(out,0,sizeof out);
memset(in,0,sizeof in);
memset(visit,false,sizeof visit);
}
void addedge(int from,int to){
edge[cnt].to=to;
edge[cnt].next=head[from];
head[from]=cnt++;
}
void TopSort(int u){//DFS拓扑排序
visit[u]=true;
for(int i=head[u];i!=-1;i=edge[i].next)
if(visit[edge[i].to]==false)
TopSort(edge[i].to);
TPO[TPOindex++]=u;
}
void DP(int n){
for(int i=n-1;i>=0;i--){
int u=TPO[i];
for(int j=head[u];j!=-1;j=edge[j].next){
int v=edge[j].to;//从终点开始对每一条边进行松弛,和Bellman_Ford有点像
dis[v]=max(dis[u]+w[v],dis[v]);
}
}
}
void solve(int n){
int TPOindex=0;
for(int i=1;i<=n;i++)
dis[i]=(in[i]==0?w[i]:-INF);//初始化dis
for(int i=1;i<=n;i++)
if(visit[i]==false)
TopSort(i);
DP(n);
}
int main(void){
#ifndef ONLINE_JUDGE
freopen("E:\\input.txt","r",stdin);
#endif // ONLINE_JUDGE
int n,m,t1,t2;
while(~scanf("%d%d",&n,&m)){
init();
for(int i=1;i<=n;i++)
scanf("%d",&w[i]);
for(int i=0;i<m;i++){
scanf("%d%d",&t1,&t2);
addedge(t1,t2);
in[t2]++,out[t1]++;
}
solve(n);
int ans=-INF;
for(int i=1;i<=n;i++)
if(out[i]==0)
ans=max(ans,dis[i]);
printf("%d\n",ans);
}
return 0;
}
POJ 3249 拓扑排序 + 简单DP
猜你喜欢
转载自blog.csdn.net/shadandeajian/article/details/81359230
今日推荐
周排行