-
C - Test for Job
- POJ - 3249
- 建立超级源点与汇点.然后跑一边拓扑序列。
- 然后按照拓扑序列中的点去更新他所到达的边.
-
#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; }
C - Test for Job POJ - 拓扑序+DAG最长路
最新推荐文章于 2019-07-04 17:44:02 发布