Test for Job POJ
阿新 • • 發佈:2018-12-18
- 建立超級源點與匯點.然後跑一邊拓撲序列。
- 然後按照拓撲序列中的點去更新他所到達的邊.
-
#include<iostream> #include<cstring> #include<stdio.h> using namespace std; #define inf 0x3f3f3f3f #define ll long long #define nn 100007 #define mm 2000007 struct node { int to,nxt; ll w; } edge[mm]; int head[nn],in[nn]; int que[nn],out[nn]; ll dis[nn],a[nn]; int n,cnt,tot,m,u,v,w; void add(int u,int v,int w) { in[v]++; out[u]++; edge[++tot].to=v; edge[tot].w=w; edge[tot].nxt=head[u]; head[u]=tot; } void topo() { que[++cnt]=0; for(int i=1; i<=cnt; i++) { int u=que[i]; for(int j=head[u]; j!=-1; j=edge[j].nxt) { int v=edge[j].to; in[v]--; if(!in[v]) que[++cnt]=v; } } } void DAG() { memset(dis,-inf,sizeof(dis)); dis[0]=0; for(int i=1; i<=cnt; i++) { int u=que[i]; for(int j=head[u]; j!=-1; j=edge[j].nxt) { int v=edge[j].to; ll w=edge[j].w; if(dis[v]<dis[u]+w) dis[v]=dis[u]+w; } } printf("%lld\n",dis[n+10]); } int main() { while(~scanf("%d%d",&n,&m)) { memset(head,-1,sizeof(head)); memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); for(int i=1; i<=n; i++) scanf("%lld",&a[i]); tot=cnt=0; while(m--) { scanf("%d%d",&u,&v); add(u,v,a[v]); } for(int i=1; i<=n; i++) { if(in[i]==0) add(0,i,a[i]); if(out[i]==0) add(i,n+10,0); } topo(); DAG(); } return 0; }