NOI 2014 魔法森林 SPFA

来源:互联网 发布:ie浏览器打不开淘宝 编辑:程序博客网 时间:2024/06/15 08:34

在一切的故事开始之前,我要说:%%%PoPoQQQ大爷!!!ORZ

这里写图片描述

————————————————————————————————————————————————————

这个题唯一的难点就是这个边的权值有两个。。。。。
可以想到枚举一个权值,然后算另一个权值最小的路径,可以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 1e9using 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[N]<ans) ans=last+dist[N];        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;}
原创粉丝点击