怎么想
模拟样例数据之后猜想:从1开始走,记着最低价格,往后一直走,不断更新差价。
但这样碰到环就麻烦了。
所以考虑缩点,DAG图能省去一些麻烦。
阿龙要低价买入,高价卖出,而每条路可以反复地走,
那么在一个强连通分量中,阿龙一定可以在该强连通分量中售价最低处买入,最高处卖出。
可以从1所在的强连通分量开始,往后走,并记录可以买到货物的最低价格,到达一个新城市群(强连通分量)
就比较当前差价是否比之前找到的差价更大。
具体怎么实现呢,
我们可以用ccnt,vheadp[ ] ,ve[ ] 这些建一个SCC图,然后在图上跑dfs
提交!
还好不是考场,还好不是MLE,TLE,之类的
下波数据看看:发现标答是2,输出了99
事情似乎明了了
需要注意的地方
答案偏大了,说明我们可能把不满足条件的城市也加进来了
为什么说是不满足条件的呢?
“读题呀,一定要仔细。”--化学老师
题目告诉我们:阿龙虽然需要在路上赚些生活费,但他的最终目的是终点n
而输入的图中,从某些点出发是不能到达终点的
所以我们构造反图,筛选一波。
再提交
NICE
#include<iostream> #include<cstdio> #include<cstring> #include<stack> #define FOR(i,n) for(register int i=1;i<=n;i++) using namespace std; const int N=100005; struct NODE{ int v,nxt; }; NODE e[N*9],ve[N*9],ne[N*9]; int head[N],vhead[N],pmin[N],pmax[N],cmin[N],cmax[N],color[N],dfn[N],ins[N],low[N]; int nhead[N],ntot; bool nvis[N]; int n,m,colorcnt,tot,vtot,timing,ans; stack <int> s; void add(int u,int v) {e[++tot].v=v;e[tot].nxt=head[u];head[u]=tot;} void vadd(int u,int v) {ve[++vtot].v=v;ve[vtot].nxt=vhead[u];vhead[u]=vtot;} void nadd(int u,int v){ne[++ntot].v=v;ne[ntot].nxt=nhead[u];nhead[u]=ntot;} void tarjan(int u) { ins[u]=1; dfn[u]=low[u]=++timing; s.push(u); for(int i=head[u];i;i=e[i].nxt) { int v=e[i].v; if(!dfn[v]) { tarjan(v); low[u]=min(low[u],low[v]); } else if(ins[v]) low[u]=min(low[u],dfn[v]); } if(dfn[u]==low[u]) { colorcnt++; cmin[colorcnt]=1e8; int tmp=s.top(); while(tmp!=u) { cmin[colorcnt]=min(cmin[colorcnt],pmin[tmp]); cmax[colorcnt]=max(cmax[colorcnt],pmax[tmp]); s.pop(); ins[tmp]=0; color[tmp]=colorcnt; tmp=s.top(); } ins[u]=0;color[u]=colorcnt;s.pop(); cmin[colorcnt]=min(cmin[colorcnt],pmin[u]); cmax[colorcnt]=max(cmax[colorcnt],pmax[u]); } } void dfs2(int nt) { if(nvis[nt]) return; nvis[nt]=1; for(int i=nhead[nt];i;i=ne[i].nxt) dfs2(ne[i].v); } void get_ans(int ccnt,int mini) { if(ins[ccnt]||!nvis[ccnt]) return; ins[ccnt]=1; ans=max(ans,cmax[ccnt]-mini); for(int i=vhead[ccnt];i;i=ve[i].nxt) { int v=ve[i].v; get_ans(v,min(mini,cmin[v])); } } int main() { //freopen("in.in","r",stdin); //freopen("out.out","w",stdout); scanf("%d%d",&n,&m); int a,b,c; FOR(i,n) cin>>pmin[i],pmax[i]=pmin[i]; FOR(i,m) { cin>>a>>b>>c; add(a,b); if(c==2) add(b,a); } FOR(i,n) if(!dfn[i]) tarjan(i); FOR(i,n) { for(int j=head[i];j;j=e[j].nxt) { int v=e[j].v; if(color[v]!=color[i]) { vadd(color[i],color[v]); nadd(color[v],color[i]); } } } dfs2(color[n]); get_ans(color[1],cmin[color[1]]); cout<<ans<<endl; return 0; }