zoukankan      html  css  js  c++  java
  • poj3463&&hdu1688 次短路(dijkstra)

        A*算法超内存。

      对于最短路,我们可以维护dis[]数组,来求得最短路,但是此题有次短路,所以定义dis[][2],dis[][0]表示最短路,dis[][1]表示次短路;cnt[][2],cnt[][0]表示最短路条数,cnt[][1]表示次短路条数。

    更新时:

    如果小于最短路,更新dis[][0]。

    如果等于最短路,更新cnt[][0]。

    如果大于最短路小于次短路,更新dis[][1];

    如果等于次短路,更新cnt[][1]。

    由于此时要求2条路,若以外层循环需要2*n-1次。

    以下为dijkstra:

    #include<stdio.h>
    #include<string.h>
    #define INF 1000000001
    const int maxn = 1020;
    const int maxm = 10010;
    struct node
    {
        int to;
        int v;
        int next;
    }edge[maxn*maxn/2];
    int pre[maxn],index,dis[maxn][2],cnt[maxn][2],n,vis[maxn][2];
    void init()
    {
        index=1;
        memset(pre,-1,sizeof(pre));
    }
    void add(int x,int y,int z)
    {
        edge[index].to=y;
        edge[index].v=z;
        edge[index].next=pre[x];
        pre[x]=index++;
    }
    void dij(int s,int t)
    {
        int i,j,k,pos;
        for(i=0;i<=n;i++)
        {
            dis[i][0]=INF;
            dis[i][1]=INF;
            cnt[i][0]=cnt[i][1]=0;
            vis[i][0]=vis[i][1]=0;
        }
        dis[s][0]=0;
        cnt[s][0]=1;
        pos=s;
        k=0;
        for(i=1;i<2*n;i++)
        {
            int min=INF;
            for(j=1;j<=n;j++)
            {
                if(!vis[j][0]&&min>dis[j][0])
                {
                    min=dis[j][0];
                    k=0;
                    pos=j;
                }
                else if(!vis[j][1]&&min>dis[j][1])
                {
                    min=dis[j][1];
                    k=1;
                    pos=j;
                }
            }
            if(min>=INF)
                break;
            vis[pos][k]=1;
            for(j=pre[pos];j!=-1;j=edge[j].next)
            {
                int v=edge[j].to;
                if(dis[v][0]>min+edge[j].v)
                {
                    dis[v][1]=dis[v][0];//
                    cnt[v][1]=cnt[v][0];
                    dis[v][0]=min+edge[j].v;
                    cnt[v][0]=cnt[pos][k];
                }
                else if(dis[v][0]==min+edge[j].v)
                {
                    cnt[v][0]+=cnt[pos][k];
                }
                else if(dis[v][1]>min+edge[j].v)
                {
                    dis[v][1]=min+edge[j].v;
                    cnt[v][1]=cnt[pos][k];
                }
                else if(dis[v][1]==min+edge[j].v)
                {
                    cnt[v][1]+=cnt[pos][k];
                }
            }
        }
        int ans=cnt[t][0];
        if(dis[t][1]==dis[t][0]+1)
            ans+=cnt[t][1];
        printf("%d
    ",ans);
    }
    int main()
    {
        int i,j,ft,m;
        scanf("%d",&ft);
        while(ft--)
        {
            init();
            scanf("%d%d",&n,&m);
            for(i=0;i<m;i++)
            {
                int x,y,z;
                scanf("%d%d%d",&x,&y,&z);
                add(x,y,z);
            }
            int s,t;
            scanf("%d%d",&s,&t);
            dij(s,t);
        }
    }

    以下为A*算法(超内存):

    #include<stdio.h>
    #include<string.h>
    #include<queue>
    #define INF 100000001
    using namespace std;
    const int maxn = 1002;
    struct node
    {
        int to;
        int g,f;
        friend bool operator<(node a,node b){
            if(a.f!=b.f)
                return a.f>b.f;
            return a.g>b.g;
        }
    };
    struct Enode
    {
        int to;
        int v;
        int next;
    }edge[10010],fedge[10010];
    int pre[maxn],index,vis[maxn],n,findex,fpre[maxn],dis[maxn];
    void init()
    {
        findex=index=1;
        memset(fpre,-1,sizeof(fpre));
        memset(pre,-1,sizeof(pre));
    }
    void add(int x,int y,int z)
    {
        edge[index].to=y;
        edge[index].v=z;
        edge[index].next=pre[x];
        pre[x]=index++;
    }
    void fadd(int x,int y,int z)
    {
        fedge[findex].to=y;
        fedge[findex].v=z;
        fedge[findex].next=fpre[x];
        fpre[x]=findex++;
    }
    void spfa(int s)
    {
        int i,j;
        queue<int>q;
        for(i=0;i<=n;i++)
        {
            vis[i]=0;
            dis[i]=INF;
        }
        dis[s]=0;
        vis[s]=1;
        q.push(s);
        while(!q.empty())
        {
            int t=q.front();
            q.pop();
            vis[t]--;
            for(i=fpre[t];i!=-1;i=fedge[i].next)
            {
                int v=fedge[i].to;
                if(dis[v]>dis[t]+fedge[i].v)
                {
                    dis[v]=dis[t]+fedge[i].v;
                    q.push(v);
                }
            }
        }
    }
    void A_star(int s,int t)
    {
        int i,j,cnt=0,first=-1;
        priority_queue<node>q;
        node temp;
        temp.f=dis[s];
        temp.g=0;
        temp.to=s;
        q.push(temp);
        while(!q.empty())
        {
            temp=q.top();
            q.pop();
            if(temp.to==t)
            {
                if(cnt==0)
                {
                    first=temp.g;
                }
                else if(temp.g-first>1)
                {
                    break;
                }
                cnt++;
            }
            for(i=pre[temp.to];i!=-1;i=edge[i].next)
            {
                node tt;
                tt.to=edge[i].to;
                tt.g=temp.g+edge[i].v;
                tt.f=tt.g+dis[tt.to];
                q.push(tt);
            }
        }
        printf("%d
    ",cnt);
    }
    int main()
    {
        int i,j,ft,m;
        scanf("%d",&ft);
    
        while(ft--)
        {
            init();
            scanf("%d%d",&n,&m);
            for(i=0;i<m;i++)
            {
                int x,y,z;
                scanf("%d%d%d",&x,&y,&z);
                add(x,y,z);
                fadd(y,x,z);
            }
            int s,t;
            scanf("%d%d",&s,&t);
            spfa(t);
            A_star(s,t);
        }
    }
  • 相关阅读:
    BNUOJ-26474 Bread Sorting 逆序对
    POJ-2480 Longge's problem 积性函数
    Bzoj-2705 Longge的问题 欧拉函数
    Bzoj-2820 YY的GCD Mobius反演,分块
    HDU-4689 Derangement DP
    [转]初学者程序语言的选择
    HDU-4705 Y 树形DP
    HDU-4704 Sum 大数幂取模
    HDU-4699 Editor 数据结构维护
    HDU-4696 Answers 纯YY
  • 原文地址:https://www.cnblogs.com/sweat123/p/4893269.html
Copyright © 2011-2022 走看看