洛谷 1073 [NOIP2009] 最优贸易 类spfa
2017-09-29 07:42
344 查看
题目:
https://www.luogu.org/problem/show?pid=1073
思路:
很明显;
DAG上的套路DP;
tarjan缩点+拓扑排序+DP;
好麻烦……
新思路:
题目有限制,要求从1点走到n点;
对于某点i,显然分为1到它的最小点权和n到它的最大点权;
于是两遍spfa,最后更新答案(当然你说是bfs也行);
注意:
这并不是真正意义上的最短路,所以不能用堆优化的dijkstra;
总结:
spfa的优点在于灵活性较好(双向,单向,有环(负环不行!),无环,正权,负权),缺点是时间复杂度比较迷,适用于稀疏图;
虽然此题表现良好,但以后还要注意;
https://www.luogu.org/problem/show?pid=1073
思路:
很明显;
DAG上的套路DP;
tarjan缩点+拓扑排序+DP;
好麻烦……
新思路:
题目有限制,要求从1点走到n点;
对于某点i,显然分为1到它的最小点权和n到它的最大点权;
于是两遍spfa,最后更新答案(当然你说是bfs也行);
注意:
这并不是真正意义上的最短路,所以不能用堆优化的dijkstra;
总结:
spfa的优点在于灵活性较好(双向,单向,有环(负环不行!),无环,正权,负权),缺点是时间复杂度比较迷,适用于稀疏图;
虽然此题表现良好,但以后还要注意;
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int MAXN=1000001; int tot,n,m,ans=-1,cnt; int fst[MAXN],nxt[MAXN],num[MAXN],dis[MAXN],cs[MAXN]; bool vis[MAXN]; struct hh { int from,to; }ma[MAXN],ss[MAXN]; void build(int f,int t) { tot++; ma[tot]=(hh){f,t}; nxt[tot]=fst[f]; fst[f]=tot; return; } void spfa1() { memset(dis,0x3f,sizeof(dis)); queue<int>q; q.push(1),vis[1]=1,dis[1]=num[1]; while(!q.empty()) { int x=q.front(); q.pop(),vis[x]=0; for(int i=fst[x];i;i=nxt[i]) { int v=ma[i].to; if(num[v]<dis[x]) { dis[v]=num[v]; if(!vis[v]) q.push(v),vis[v]=1; } else if(dis[v]>dis[x]) { dis[v]=dis[x]; if(!vis[v]) q.push(v),vis[v]=1; } } } return; } void add(int f,int t) { ++cnt; ss[cnt]=(hh){f,t}; nxt[cnt]=fst[f]; fst[f]=cnt; return; } void spfa2() { memset(vis,0,sizeof(vis)); memset(fst,0,sizeof(fst)); memset(cs,0,sizeof(cs)); memset(nxt,0,sizeof(nxt)); queue<int>q; q.push(n),vis =1,dis =num ; for(int i=1;i<=tot;i++) add(ma[i].to,ma[i].from); while(!q.empty()) { int x=q.front(); q.pop(),vis[x]=0; for(int i=fst[x];i;i=nxt[i]) { int v=ss[i].to; if(num[v]>cs[x]) { cs[v]=num[v]; if(!vis[v]) q.push(v),vis[v]=1; } else if(cs[v]<cs[x]) { cs[v]=cs[x]; if(!vis[v]) q.push(v),vis[v]=1; } } } } void solve() { cin>>n>>m; for(int i=1;i<=n;i++) scanf("%d",&num[i]); for(int i=1;i<=m;i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); if(z==1) build(x,y); else build(x,y),build(y,x); } spfa1(),spfa2(); for(int i=1;i<=n;i++) ans=max(cs[i]-dis[i],ans); cout<<ans; } int main() { solve(); return 0; }
相关文章推荐
- luogu1073 【noip2009提高】最优贸易(spfa)
- 【NOIP2009】洛谷1073 最优贸易【解法一】
- 【NOIP2009】洛谷1073 最优贸易【解法二】
- NOIP2009-T3 洛谷-1073 最优贸易
- 【Spfa】noip2009 最优贸易
- 【NOIP2009】最优贸易 spfa
- 【双向spfa】【noip2009】最优贸易 trade
- SPFA——Luogu1073 [NOIP2009]最优贸易
- [NOIP 2009]最优贸易 Spfa
- 【NOIP2009】洛谷P1073 最优贸易(SPFA + 反向建图)
- 洛谷 1073_最优贸易_spfa+dfs
- 洛谷1037 NOIP2009 最优贸易
- 【 洛谷P1073 】【NOIP2009】最优贸易
- [NOIP2009][spfa]最优贸易
- 洛谷 P1073 [NOIP2009 T3] 最优贸易
- 【双向spfa】【noip2009】最优贸易 trade
- LG1073【NOIp2009】最优贸易 <Tarjan+DP>
- NOIP2009T3最优贸易(Dfs + spfa)
- [NOIP2009]最优贸易(spfa)
- [NOIP2009]最优贸易【spfa,dp,强联…