P1073 最优贸易
//Pro:NOIP2009 T3 P1073 最优贸易 //Sol:先用tarjan缩点,得到一个DAG,然后在DAG上拓扑即可。 #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<stack> #include<queue> using namespace std; const int N=1e5+5; const int M=5e5+5; inline int read() { char c=getchar();int num=0; for(;!isdigit(c);c=getchar()); for(;isdigit(c);c=getchar()) num=num*10+c-'0'; return num; } int n,m; int head[N],num_edge,num_edg; struct Edge { int u,v,nxt; }edge[M<<1],edg[N]; int prize[N]; inline void add_edge(int u,int v) { edge[++num_edge].u=u; edge[num_edge].v=v; edge[num_edge].nxt=head[u]; head[u]=num_edge; } inline void add(int u,int v) { edg[++num_edg].v=v; edg[num_edg].nxt=head[u]; head[u]=num_edg; } int dfn[N],low[N],tim; bool insta[N]; int belong[N],cnt; int maxn[N],minn[N]; stack<int> sta; void tarjan(int now) { dfn[now]=low[now]=++tim; sta.push(now),insta[now]=1; for(int i=head[now],v;i;i=edge[i].nxt) { v=edge[i].v; if(!dfn[v]) { tarjan(v); low[now]=min(low[now],low[v]); } else if(insta[v]) low[now]=min(low[now],dfn[v]); } if(low[now]==dfn[now]) { int tmp; ++cnt; minn[cnt]=999999999,maxn[cnt]=-1; do { tmp=sta.top(),sta.pop(); belong[tmp]=cnt; insta[tmp]=0; maxn[cnt]=max(maxn[cnt],prize[tmp]); minn[cnt]=min(minn[cnt],prize[tmp]); }while(tmp!=now); } } int rudu[N]; queue<int> que; int f[N]; void topsort() { que.push(belong[1]); f[belong[1]]=maxn[belong[1]]-minn[belong[1]]; int now; while(!que.empty()) { now=que.front(),que.pop(); for(int i=head[now],v;i;i=edg[i].nxt) { v=edg[i].v; --rudu[v]; minn[v]=min(minn[v],minn[now]); f[v]=max(f[now],maxn[v]-minn[v]); if(!rudu[v]) que.push(v); } } } int main() { // freopen("233.in","r",stdin); n=read(),m=read(); for(int i=1;i<=n;++i) prize[i]=read(); for(int i=1,u,v,t;i<=m;++i) { u=read(),v=read(),t=read(); add_edge(u,v); if(t==2) add_edge(v,u); } for(int i=1;i<=n;++i) if(!belong[i]) tarjan(i); // cout<<cnt<<endl; memset(head,0,sizeof(head)); for(int i=1;i<=num_edge;++i) { if(belong[edge[i].u]!=belong[edge[i].v]) { add(belong[edge[i].u],belong[edge[i].v]); ++rudu[belong[edge[i].v]]; } } topsort(); printf("%d",f[belong[n]]>0?f[belong[n]]:0); return 0; }