• 0x61 最短路


    终于会dij了原来我以前写的也是堆优化spfa-_-!

    poj3662DP 通过spfa来放缩(可怜我去年NOIP的day1t3啊)

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    struct node
    {
        int x,y,d,next;
    }a[21000];int len,last[1100];
    void ins(int x,int y,int d)
    {
        len++;
        a[len].x=x;a[len].y=y;a[len].d=d;
        a[len].next=last[x];last[x]=len;
    }
    
    int list[1100];
    int f[1100][1100];bool v[1100];
    int main()
    {
        int n,m,K,x,y,d;
        scanf("%d%d%d",&n,&m,&K);
        len=0;memset(last,0,sizeof(last));
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&x,&y,&d);
            ins(x,y,d);ins(y,x,d);
        }
        
        int head=1,tail=2;list[1]=1;
        memset(f,63,sizeof(f));f[1][0]=0;
        memset(v,false,sizeof(v));v[1]=true;
        while(head!=tail)
        {
            int x=list[head];
            for(int k=last[x];k;k=a[k].next)
            {
                int y=a[k].y;
                for(int p=0;p<=K;p++)
                {
                    int tt=f[y][p];
                    if(p!=0)f[y][p]=min(f[y][p],f[x][p-1]);
                    f[y][p]=min(f[y][p],max(f[x][p],a[k].d));
                    
                    if(tt!=f[y][p]&&v[y]==false)
                    {
                        v[y]=true;
                        list[tail]=y;
                        tail++;if(tail==1050)tail=1;
                    }
                }
            }
            v[x]=false;
            head++;if(head==1050)head=1;
        }
        if(f[n][K]==f[0][0])printf("-1
    ");
        else printf("%d
    ",f[n][K]);
        return 0;
    }
    poj3662

    最优贸易 正反dij分别求最小和最大,然后mx[x]-mn[x]就好(怎么这个专题净勾起我的伤心事啊,初一的某模拟赛就是没还原v数组100变没分啊啊啊)

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    using namespace std;
    
    struct node{int x,y,next;}a[1100000],e[1100000];
    int alen,elen,alast[110000],elast[110000];
    void ains(int x,int y)
    {
        alen++;
        a[alen].x=x;a[alen].y=y;
        a[alen].next=alast[x];alast[x]=alen;
    }
    void eins(int x,int y)
    {
        elen++;
        e[elen].x=x;e[elen].y=y;
        e[elen].next=elast[x];elast[x]=elen;
    }
    
    struct dij
    {
        int k,id;
        dij(){}
        dij(int K,int ID){k=K;id=ID;}
        friend bool operator>(dij d1,dij d2){return d1.k>d2.k;}
        friend bool operator<(dij d1,dij d2){return d1.k<d2.k;}
    }; 
    priority_queue<dij,vector<dij>,greater<dij> >aq;
    priority_queue<dij>eq;
    int mn[110000],mx[110000];bool v[110000],inq[110000];
    
    int w[110000];
    int main()
    {
        int n,m,x,y,op;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d",&w[i]);
        alen=0;memset(alast,0,sizeof(alast));
        elen=0;memset(elast,0,sizeof(elast));
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&x,&y,&op);
            if(op==1)
                ains(x,y), eins(y,x);
            else
                ains(x,y),ains(y,x), eins(x,y),eins(y,x);
        }
        
        memset(v,false,sizeof(v));
        memset(inq,false,sizeof(inq));inq[1]=true;
        mn[1]=w[1]; aq.push(dij(w[1],1));
        while(!aq.empty())
        {
            dij tno=aq.top();aq.pop();
            if(v[tno.id]==true)continue;
            v[tno.id]=true;
            
            int x=tno.id;
            for(int k=alast[x];k;k=a[k].next)
            {
                int y=a[k].y;
                if(inq[y]==false)
                    inq[y]=true, mn[y]=w[y], aq.push(dij(mn[y],y));
                if(mn[y]>tno.k)
                {
                    mn[y]=tno.k;
                    aq.push(dij(mn[y],y));
                }
            }
        }
        
        memset(v,false,sizeof(v));
        memset(inq,false,sizeof(inq));inq[1]=true;
        mx[n]=w[n], eq.push(dij(w[n],n));
        while(!eq.empty())
        {
            dij tno=eq.top();eq.pop();
            if(v[tno.id]==true)continue;
            v[tno.id]=true;
            
            int x=tno.id;
            for(int k=elast[x];k;k=e[k].next)
            {
                int y=e[k].y;
                if(inq[y]==false)
                    inq[y]=true, mx[y]=w[y], eq.push(dij(mx[y],y));
                if(mx[y]<tno.k)
                {
                    mx[y]=tno.k;
                    eq.push(dij(mx[y],y));
                }
            }
        }
        
        int ans=0;
        for(int i=1;i<=n;i++)
            ans=max(ans,mx[i]-mn[i]);
        printf("%d
    ",ans);
        /*
        for(int i=1;i<=n;i++)printf("%d ",mx[i]);
        printf("
    ");
        for(int i=1;i<=n;i++)printf("%d ",mn[i]);
        printf("
    ");*/
        return 0;
    }
    最优贸易

    bzoj2200 这题卡spfa(然而用酸辣粉和啦(fan)啦(you)啦(hua)这两个玄学优化可以过)

    正解呢是topsort+dij,因为把正边看成联通块,负边其实构成的是一个DAG图,所以拓扑排序时顺便把环dij一次

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    using namespace std;
    
    struct node
    {
        int x,y,d,next;
    }a[110000];int len,last[31000];
    void ins(int x,int y,int d)
    {
        len++;
        a[len].x=x;a[len].y=y;a[len].d=d;
        a[len].next=last[x];last[x]=len;
    }
    int fa[31000];
    int findfa(int x)
    {
        if(fa[x]==x)return x;
        fa[x]=findfa(fa[x]);return fa[x];
    }
    
    int d[31000];
    struct dij
    {
        int k,id;
        dij(){}
        dij(int K,int ID){k=K;id=ID;}
        friend bool operator>(dij d1,dij d2){return d1.k>d2.k;}
        friend bool operator<(dij d1,dij d2){return d1.k<d2.k;}
    }; bool v[31000];
    priority_queue<dij,vector<dij>,greater<dij> >q;
    void dijkstra(int st,int k)
    {
        if(d[st]<=k)return ;
        d[st]=k;q.push(dij(d[st],st));
        memset(v,false,sizeof(v));
        while(!q.empty())
        {
            dij tno=q.top();q.pop();
            if(v[tno.id]==true)continue;
            v[tno.id]=true;
            
            int x=tno.id;
            for(int k=last[x];k;k=a[k].next)
            {
                int y=a[k].y;
                if(d[y]>d[x]+a[k].d)
                {
                    d[y]=d[x]+a[k].d;
                    q.push(dij(d[y],y));
                }
            }
        }
    }
    
    //----------------合并成联通块+dijkstra处理正环---------------------
    
    struct enode
    {
        int fx,fy,x,y,d,next;
    }e[110000];int elen,elast[31000];
    void eins(int fx,int fy,int x,int y,int d)
    {
        elen++;
        e[elen].fx=fx;e[elen].fy=fy;
        e[elen].x=x;e[elen].y=y;e[elen].d=d;
        e[elen].next=elast[fx];elast[fx]=elen;
    }
    int du[31000],n,S;
    int top,sta[31000];
    void topsort()
    { 
        top=0;sta[++top]=0;
        eins(0,findfa(S),0,S,0),du[findfa(S)]++;
        for(int i=1;i<=n;i++)
            if(findfa(i)==i&&du[i]==0&&i!=findfa(S))
                sta[++top]=i;
        while(top!=1)
        {
            int fx=sta[top];top--;
            for(int k=elast[fx];k;k=e[k].next)
            {
                du[e[k].fy]--;
                if(du[e[k].fy]==0)sta[++top]=e[k].fy;
            }
        }
        while(top!=0)
        {
            int fx=sta[top];top--;
            for(int k=elast[fx];k;k=e[k].next)
            {
                dijkstra(e[k].y,d[e[k].x]+e[k].d);
                du[e[k].fy]--;
                if(du[e[k].fy]==0)sta[++top]=e[k].fy;
            }
        }
    }
    
    //--------------topsort-------------------- 
    
    int main()
    {
        int R,P,x,y,dd;
        scanf("%d%d%d%d",&n,&R,&P,&S);
        len=0;memset(last,0,sizeof(last));
        for(int i=1;i<=n;i++)fa[i]=i;
        for(int i=1;i<=R;i++)
        {
            scanf("%d%d%d",&x,&y,&dd);
            ins(x,y,dd);ins(y,x,dd);
            
            int fx=findfa(x),fy=findfa(y);
            fa[fx]=fy;
        }
        
        memset(du,0,sizeof(du));
        for(int i=1;i<=P;i++)
        {
            scanf("%d%d%d",&x,&y,&dd);
            int fx=findfa(x),fy=findfa(y);
            eins(fx,fy,x,y,dd);
            du[fy]++;
        }
        memset(d,63,sizeof(d));d[0]=0;
        topsort();
        
        for(int i=1;i<=n;i++)
            if(d[i]==d[n+1])printf("NO PATH
    ");
            else printf("%d
    ",d[i]);
        return 0;
    }
    bzoj2200

    poj1734 floyd求最小环,考虑对于一个环,把它拆分成前k-1个点和第k个点,当floyd完k-1次,得到的就是利用前k-1个点相互到达的最短路,此时再加上第k个点构成环,保证不重复,同时,取最大的点和取其他点,效果是一样的。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    int a[110][110],mp[110][110];
    int len,as[110],pos[110][110];
    void getpath(int i,int j)
    {
        if(pos[i][j]==0)return ;
        getpath(i,pos[i][j]);
        as[++len]=pos[i][j];
        getpath(pos[i][j],j);
    }
    
    int main()
    {
        freopen("TRIP.in","r",stdin);
        freopen("TRIP.out","w",stdout);
        int n,m,x,y,d;
        scanf("%d%d",&n,&m);
        memset(mp,63,sizeof(mp));
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&x,&y,&d);
            mp[x][y]=min(mp[x][y],d);
            mp[y][x]=min(mp[y][x],d);
        }
        memcpy(a,mp,sizeof(mp));
        
        int ans=mp[0][0];
        memset(pos,0,sizeof(pos));
        for(int k=1;k<=n;k++)
        {
            for(int i=1;i<k;i++)
                for(int j=i+1;j<k;j++)
                {
                    if((long long)mp[i][j]+a[i][k]+a[k][j]<ans)
                    {
                        ans=mp[i][j]+a[i][k]+a[k][j];
                        len=0;
                        as[++len]=i;
                        getpath(i,j);
                        as[++len]=j;
                        as[++len]=k;
                    }
                }
                
            for(int i=1;i<=n;i++) if(i!=k)
                for(int j=1;j<=n;j++) if(j!=k&&j!=i)
                    if(mp[i][j]>mp[i][k]+mp[k][j])
                    {
                        mp[i][j]=mp[i][k]+mp[k][j];
                        pos[i][j]=k;
                    }
        }
        if(ans==mp[0][0])printf("No solution.
    ");
        else
        {
            for(int i=1;i<len;i++)printf("%d ",as[i]);
            printf("%d
    ",as[len]);
        }
    
        return 0;
    }
    poj1734

    poj3613 神仙题

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    struct line{int d,x,y;}li[110];
    int n,ls[210];
    struct Matrix{int mp[110][110];}A,ans;
    Matrix calc(Matrix a,Matrix b)
    {
        Matrix c;
        memset(c.mp,63,sizeof(c.mp));
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                for(int k=1;k<=n;k++)
                    c.mp[i][j]=min(c.mp[i][j],a.mp[i][k]+b.mp[k][j]);
        return c;
    }
    int main()
    {
        int m,P,S,E;
        scanf("%d%d%d%d",&P,&m,&S,&E);
        n=0;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&li[i].d,&li[i].x,&li[i].y);
            ls[++n]=li[i].x;
            ls[++n]=li[i].y;
        }
        sort(ls+1,ls+n+1);
        n=unique(ls+1,ls+n+1)-ls-1;
        for(int i=1;i<=m;i++)
        {
            li[i].x=lower_bound(ls+1,ls+n+1,li[i].x)-ls;
            li[i].y=lower_bound(ls+1,ls+n+1,li[i].y)-ls;
        }
        S=lower_bound(ls+1,ls+n+1,S)-ls;
        E=lower_bound(ls+1,ls+n+1,E)-ls;
        //LSH
        
        memset(A.mp,63,sizeof(A.mp));
        for(int i=1;i<=m;i++)
        {
            int x=li[i].x,y=li[i].y;
            A.mp[x][y]=min(A.mp[x][y],li[i].d);
            A.mp[y][x]=min(A.mp[y][x],li[i].d);
        }
        memcpy(ans.mp,A.mp,sizeof(A.mp));
        P--;
        while(P!=0)
        {
             if(P%2==1)ans=calc(ans,A);
            A=calc(A,A);P/=2;
        }
        printf("%d
    ",ans.mp[S][E]);
        return 0;
    }
    poj3613
  • 相关阅读:
    23中设计模式详解
    C#中的partial,this关键字以及扩展方法
    笨重WebService与轻快的RestFul
    彻底理解Web Service
    WebService中的瘦客户端与富客户端
    [转]Sql Or NoSql,看完这一篇你就懂了
    [转]Mysql字符串截取总结:left()、right()、substring()、substring
    [转]ASP.NET Core on K8s 入门学习系列文章目录
    [转]CSDN-markdown语法之怎样使用LaTeX语法编写数学公式
    [转]我在传统行业做数字化转型(1)预告篇
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/9518685.html
Copyright © 2020-2023  润新知