1. 程式人生 > >poj 1511 鄰接表+堆優化的dijstra

poj 1511 鄰接表+堆優化的dijstra

這題最終的意思很簡單,輸入圖,求出從源點到所有點的最短路,再把這個圖的所有邊反向,再求一次源點到所有點的最短路。

這個和poj另一道題很相似,合適這題 的意義在於資料。

你這個圖是無法用鄰接矩陣存下的,因為鄰接矩陣太大了,你只能用鄰接表。

那麼這個題就是用鄰接表的用優先佇列優化過的dijstra過的了。

(其實堆優化就是用優先佇列而已,不和那些人裝樣子……)

注意這個圖的所有邊反向是怎麼實現的。

AC程式碼:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
using namespace std;
const int maxe=1e6+10;
const int maxv=1e6+10;
const int inf=0x3f3f3f3f;
typedef long long ll;

int  N,M;
int restore[maxe][3];
int which=1;
int head[maxv];
struct EDGE
{
    int d,w,next;
    EDGE():next(-1){}
}e[maxv];
void add(int s, int d,int w)
{
    e[which].d=d;
    e[which].w=w;
    e[which].next=head[s];
    head[s]=which++;
}
void initforgraph()
{
    memset(head,-1,sizeof(head));
    memset(e,0,sizeof(e));
}


struct pnwdis
{
    int pn,dist;
    friend bool operator<(pnwdis a,pnwdis b)
    {
        return a.dist>b.dist;
    }
};
int dis[maxv];
void dijstra(int st)
{
    bool settled[maxv];
    priority_queue<pnwdis> Q;
    memset(settled,0,sizeof(settled));
    while(!Q.empty()) Q.pop();
    for(int i=1;i<=N;i++) dis[i]=inf;
    dis[st]=0;

    pnwdis stt;
    stt.pn=st; stt.dist=0;
    Q.push(stt);
    while(!Q.empty())
    {
        pnwdis t=Q.top();
        Q.pop();
        if(settled[t.pn]) continue;
        settled[t.pn]=1;

        for(int i=head[t.pn];i!=-1;i=e[i].next)
        {
            int to=e[i].d;
            int mid=t.pn;
            if(!settled[to])
            {
                if(dis[to]>dis[mid]+e[i].w)
                {
                    dis[to]=dis[mid]+e[i].w;
                    pnwdis tt;
                    tt.pn=to;
                    tt.dist=dis[to];
                    Q.push(tt);
                }
            }
        }
    }
}
void print()
{
    for(int i=1;i<=N;i++)
    {
        printf("%d ",dis[i]);
    }
    printf("\n");
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        ll ans=0;
        scanf("%d%d",&N,&M);


        which=1;
        initforgraph();
        int t1,t2,t3;
        for(int i=1;i<=M;i++)
        {
            scanf("%d%d%d",&t1,&t2,&t3);
            restore[i][0]=t1;
            restore[i][1]=t2;
            restore[i][2]=t3;
            add(t1,t2,t3);
        }
        dijstra(1);
        for(int i=1;i<=N;i++)
            ans+=dis[i];

        initforgraph();
        which=1;
        for(int i=1;i<=M;i++)
        {
            add(restore[i][1],restore[i][0],restore[i][2]);
        }
        dijstra(1);
        for(int i=1;i<=N;i++)
            ans+=dis[i];

        cout<<ans<<endl;
    }
}
程式碼有點長……不好意思水平有限……