关于样例和数据

P1073 [NOIP2009 提高组] 最优贸易

tarjan缩点+topu+dp ```cpp #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<queue> #include<stack> #define maxn 1000001 using namespace std; int n,m; struct pp { int next,to; }a1[maxn],a2[maxn]; int vis[maxn]; int into[maxn]; int w1[maxn],w2[maxn]; int maxx[maxn]; int head1[maxn],head2[maxn]; int t1,t2; int price[maxn]; int x[maxn],y[maxn]; int color[maxn]; int dfn[maxn]; int num; int dis[maxn]; int sum; int low[maxn]; int dep[maxn]; int dp[maxn]; int minc[maxn]; int ans; stack<int> s; void add1(int u,int v) { a1[++t1].next=head1[u]; a1[t1].to=v; head1[u]=t1; } void add2(int u,int v) { a2[++t2].next=head2[u]; a2[t2].to=v; head2[u]=t2; } void tarjan(int x) { dfn[x]=low[x]=++num; s.push(x); vis[x]=1; for(int i=head1[x];i;i=a1[i].next) { if(!dfn[a1[i].to]) { tarjan(a1[i].to); low[x]=min(low[x],low[a1[i].to]); } else if(vis[a1[i].to]) { low[x]=min(low[x],dfn[a1[i].to]); } } if(dfn[x]==low[x]) { sum++; while(s.top()!=x) { vis[s.top()]=0; color[s.top()]=sum; s.pop(); } vis[s.top()]=0; color[s.top()]=sum; s.pop(); } return ; } void topu() { queue<int> q; for(int i=1;i<=sum;i++) { if(!into[i]) q.push(i); } while(!q.empty()) { int x=q.front(); q.pop(); dep[++ans]=x; for(int i=head2[x];i;i=a2[i].next) { int v=a2[i].to; into[a2[i].to]--; if(into[v]==0) q.push(v); } } memset(minc,0x3f,sizeof(minc)); minc[dep[1]]=w2[dep[1]]; for(int i=1;i<=ans;i++) { int x=dep[i]; for(int j=head2[x];j;j=a2[j].next) { int u=a2[j].to; minc[u]=min(minc[u],min(minc[x],w2[x])); dp[u]=max(dp[u],max(dp[x],max(maxx[u],w1[u]-minc[u]))); } } cout<<dp[color[n]]; } int main() { memset(w2,0x3f,sizeof(w2)); cin>>n>>m; for(int i=1;i<=n;i++) cin>>price[i]; for(int i=1;i<=m;i++) { int a,b,z; cin>>a>>b>>z; if(z==2) { add1(a,b); add1(a,b); } if(z==1) add1(a,b); } for(int i=1;i<=n;i++) { if(!dfn[i]) tarjan(i); } for(int i=1;i<=n;i++) for(int j=head1[i];j;j=a1[j].next) { int u=a1[j].to; if(color[i]!=color[u]) { add2(color[i],color[u]); into[color[u]]++; } } for(int i=1;i<=n;i++) { w1[color[i]]=max(w1[color[i]],price[i]); w2[color[i]]=min(w2[color[i]],price[i]); } for(int i=1;i<=sum;i++) maxx[i]=w1[i]-w2[i]; topu(); return 0; } ```
by Ruff @ 2018-07-24 21:31:46


@[Ruff](/space/show?uid=30205) 数据水被你水过去了
by henry_y @ 2018-07-24 21:49:33


@[henry_y](/space/show?uid=36526) 大犇请指教
by Ruff @ 2018-07-25 20:33:03


@[henry_y](/space/show?uid=36526) 你加双向边的时候加成了两个单向边
by 青珹 @ 2018-09-21 18:41:36


@[Ruff](/space/show?uid=30205) 抱歉,@ 错了……
by 青珹 @ 2018-09-21 19:37:40


|