NOI 2014 魔法森林 SPFA
2017-09-11 19:53
253 查看
在一切的故事开始之前,我要说:%%%PoPoQQQ大爷!!!ORZ
————————————————————————————————————————————————————
这个题唯一的难点就是这个边的权值有两个。。。。。
可以想到枚举一个权值,然后算另一个权值最小的路径,可以SPFA搞定。但是呢我就蒙蔽了。。。TL妥妥的怎么破ORZ
这个时候就需要PoPoQQQ大爷的帮助了:“这里要用的SPFA的动态加点(边)法 我们每加一条边 就把边的两端点入队 继续SPFA 不用对f数组进行memset”(f是我的dist)
于是问题得以解决。(但是有点小慢啊我好像是输在了系统栈上QAQ)
%%%%%%%%%%%%%%
AC代码:
————————————————————————————————————————————————————
这个题唯一的难点就是这个边的权值有两个。。。。。
可以想到枚举一个权值,然后算另一个权值最小的路径,可以SPFA搞定。但是呢我就蒙蔽了。。。TL妥妥的怎么破ORZ
这个时候就需要PoPoQQQ大爷的帮助了:“这里要用的SPFA的动态加点(边)法 我们每加一条边 就把边的两端点入队 继续SPFA 不用对f数组进行memset”(f是我的dist)
于是问题得以解决。(但是有点小慢啊我好像是输在了系统栈上QAQ)
%%%%%%%%%%%%%%
AC代码:
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> #include<set> #include<map> #include<vector> #include<cctype> #include<ctime> #define inf 1e9 using namespace std; const int maxn=50005; const int maxm=100005; int N,M; struct edge{ int from,to,next,a,b; }E[maxm<<1],EE[maxm<<1]; int first[maxn],np,np2,dist[maxn]; bool inq[maxn]; int ans=inf; void _scanf(int &x) { x=0; char ch=getchar(); while(ch<'0'||ch>'9') ch=getchar(); while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); } void add_edge1(int u,int v,int a,int b) { EE[++np]=(edge){u,v,0,a,b}; } void add_edge2(edge e) { E[++np]=e; E[np].next=first[e.from]; first[e.from]=np; } void data_in() { _scanf(N);_scanf(M); int x,y,a,b; for(int i=1;i<=M;i++) { _scanf(x);_scanf(y);_scanf(a);_scanf(b); add_edge1(x,y,a,b); add_edge1(y,x,a,b); } } bool cmp(edge x,edge y) { return x.a<y.a; } void SPFA() { sort(EE+1,EE+np+1,cmp); M*=2,np=0; queue<int>q; memset(inq,0,sizeof(inq)); for(int i=1;i<=N;i++) dist[i]=inf; dist[1]=0; int last=EE[1].a,i=1,ii,j,now; while(i<=M) { while(i<=M && EE[i].a==last) { add_edge2(EE[i++]); if(!inq[E[np].from]) { q.push(E[np].from); inq[E[np].from]=1; } if(!inq[E[np].to]) { q.push(E[np].to); inq[E[np].to]=1; } } while(!q.empty()) { ii=q.front();q.pop(); inq[ii]=0; for(int p=first[ii];p;p=E[p].next) { j=E[p].to; now=max(dist[ii],E[p].b); if(now<dist[j]) { dist[j]=now; if(!inq[j]) { q.push(j); inq[j]=1; } } } } if(last+dist <ans) ans=last+dist ; last=EE[i].a; } if(ans==inf) ans=-1; printf("%d\n",ans); } int main() { freopen("test.in","r",stdin); freopen("test.out","w",stdout); data_in(); SPFA(); return 0; }
相关文章推荐
- 【bzoj3669】【noi2014】【魔法森林】【spfa】
- BZOJ 3669: [Noi2014]魔法森林 [LCT Kruskal | SPFA]
- [BZOJ3669][Noi2014]魔法森林(动态spfa)
- 【BZOJ3669】【NOI2014】魔法森林 (spfa动态队列加点算法)
- 神spfa [Noi2014]魔法森林
- bzoj3669【NOI2014】魔法森林 SPFA
- BZOJ 3669 NOI2014 魔法森林 SPFA
- 【BZOJ 3669】 3669: [Noi2014]魔法森林 (动态spfa)
- BZOJ 3669 [Noi2014]魔法森林 ——SPFA / Link-Cut Tree
- [BZOJ 3669][Noi2014]魔法森林:SPFA
- NOI2014 魔法森林 day1t2 SPFA
- BZOJ 3669: [Noi2014]魔法森林 动点spfa
- bzoj 3669: [Noi2014]魔法森林 -- 动点spfa
- BZOJ3669 [Noi2014]魔法森林(SPFA+动态加边)
- bzoj3669 [Noi2014]魔法森林
- NOI2014 魔法森林 (动态树)
- bzoj 3669: [Noi2014]魔法森林 link cut tree
- 【bzoj3669】[Noi2014]魔法森林
- ☆ [NOI2014] 魔法森林 「LCT动态维护最小生成树」
- [Noi2014]魔法森林( 动态mst lct)