bzoj3040: 最短路(road)

来源:互联网 发布:苹果电脑怎么编译c语言 编辑:程序博客网 时间:2024/05/24 03:54

这题看题目,TYB大佬说肯定不是最短路。。
然而一打开,提示就写着最短路。。
于是就写啊
一开始用dij+stl的普通priority_queue
然后MLE了

于是上网找了一下原因,发现是同一个点进栈太多。。
于是发现又一个很强的东西——配对堆。。
据说除了修改logn,其他都是O(1),感觉很劲啊!!
去学了一波。。感觉其实也没怎么学。。主要应该时要背代码

然后呢,网上有一个直接用priority_queue的做法,是骗人的。。我仔细看了很久,发现他吧随机生成的边删掉了。。
smg。。这都可以A。。

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<queue>#include<ext/pb_ds/priority_queue.hpp>using namespace std;using namespace __gnu_pbds;typedef long long LL;const int M=10000005;const int N=1000005;int n,m;//T、rxa、rxc、rya、ryc、rpstruct qq{    int y,z,last;}s[M];int num,last[N];LL f[N];typedef __gnu_pbds::priority_queue<pair<LL,int> > heap;heap::point_iterator id[1000005];  void Get_ans (){    heap q;    memset(f,127,sizeof(f));    id[1]=q.push(make_pair(0,1));    f[1]=0;    while (!q.empty())    {        int x=q.top().second;q.pop();        if (x==n) break;        for (int u=last[x];u!=-1;u=s[u].last)        {            int y=s[u].y;            if (f[y]>f[x]+s[u].z)            {                f[y]=f[x]+s[u].z;                if (id[y]!=0) q.modify(id[y],make_pair(-f[y],y));                else id[y]=q.push(make_pair(-f[y],y));            }        }    }    printf("%lld\n",f[n]);}void init (int x,int y,int z){    num++;    s[num].y=y;s[num].z=z;    s[num].last=last[x];    last[x]=num;}inline int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}int main(){    num=0;    memset(last,-1,sizeof(last));    n=read();m=read();    int T=read(),rxa=read(),rxc=read(),rya=read(),ryc=read(),rp=read();    int x=0,y=0,z=0;    for (int u=1;u<=T;u++)    {        x=((LL)x*rxa+rxc)%rp;        y=((LL)y*rya+ryc)%rp;        int a=min(x%n+1,y%n+1);        int b=max(x%n+1,y%n+1);        init(a,b,1e8-100*a);    }    for (int u=T+1;u<=m;u++)    {        int a=read(),b=read(),c=read();        init(a,b,c);    }    Get_ans();    return 0;}/*1.初始化x=y=z=02.重复以下过程T次:x=(x*rxa+rxc)%rp;y=(y*rya+ryc)%rp;a=min(x%n+1,y%n+1);b=max(x%n+1,y%n+1);*/