### hdu4725The Shortest Path in Nya Graph(拆點 + 最短路dijkstra | SPFA)

j--->i + n連一條權為0的邊，i + n + n --->j連一條權為0的邊。對於層與層之間的關系，因為層抽象出來的點只是一個中間媒介點，所以對於進入第i層的邊，只可能通過i+n這個點直接從隔壁層出去，於是i+n--->i +1 + n + n連邊，邊權c，i + n +1 --->i + n + n連邊，邊權c。注意雖然第i層被抽象出了i+n和I+ n + n2個點，但他們之間不能連邊，因為同一層的點距離不為0，連邊了就失去了拆點的意義。

trick：n可以為0。。。

1：dijkstra+優先隊列：

`#include <iostream>#include<cstdio>#include<queue>#include<cstring>#include<algorithm>using namespace std;const int N = 300005;const int M = 10000005;const int inf = 0x3f3f3f3f;int m,n,c,num;int head[N];int dis[N];bool flag[N];struct nd{    int dist,id;    bool operator< (const nd &a)const    {        return dist > a.dist;    }}ss,st;priority_queue<nd>lcm;struct node{    int to,next,w;}g[M];void build(int s,int e,int w){    g[num].to = e;    g[num].w = w;    g[num].next = head[s];    head[s] = num ++;}void dijkstra(){    int i,u;    ss.dist = 0;    ss.id = 1;    dis[1] = 0;    while(!lcm.empty())        lcm.pop();    lcm.push(ss);    while(!lcm.empty())    {        ss = lcm.top();        lcm.pop();        u = ss.id;        if(flag[u])            continue;        flag[u] = true;        for(i = head[u];i != -1;i = g[i].next)        {            if(flag[g[i].to] == false && dis[g[i].to] > dis[u] + g[i].w)            {                dis[g[i].to] = dis[u] + g[i].w;                ss.dist = dis[g[i].to];                ss.id = g[i].to;                lcm.push(ss);            }        }    }}int main(){    int i,a,b,t,cas = 0;    int level;    scanf("%d",&t);    while(t --)    {        scanf("%d%d%d",&n,&m,&c);        memset(head,-1,sizeof(head));        num = 0;        for(i = 1;i < n;i ++)        {            build(n + i + 1,n + n + i,c);            build(n + i,n + n + i + 1,c);        }        for(i = 1;i <= n;i ++)        {            dis[i] = dis[i + n] = dis[i + n + n] = inf;            flag[i] = flag[i + n] = flag[i + n + n] = false;            scanf("%d",&level);            build(i,n + level,0);            build(n + n + level,i,0);        }        for(i = 1;i <= m;i ++)        {            scanf("%d%d%d",&a,&b,&level);            build(a,b,level);            build(b,a,level);        }        printf("Case #%d: ",++cas);        dijkstra();        if(dis[n] == inf || n == 0)            dis[n] = -1;        printf("%d\n",dis[n]);    }    return 0;}//234MS10584K`

2：SPFA：

`#include <iostream>#include<cstdio>#include<queue>#include<cstring>#include<algorithm>using namespace std;const int N = 300005;const int M = 10000005;const int inf = 0x3f3f3f3f;int m,n,c,num;int head[N];int dis[N];bool flag[N];struct nd{    int dist,id;    bool operator< (const nd &a)const    {        return dist > a.dist;    }}ss,st;int que[M];struct node{    int to,next,w;}g[M];void build(int s,int e,int w){    g[num].to = e;    g[num].w = w;    g[num].next = head[s];    head[s] = num ++;}void SPFA(){    int i;    dis[1] = 0;    flag[1] = true;    int front,rear;    front = rear = 0;    que[rear ++] = 1;    while(front != rear)    {        int u = que[front ++];        flag[u] = false;        if(front == M)            front = 0;        for(i = head[u];i != -1;i = g[i].next)        {            if(dis[g[i].to] > dis[u] + g[i].w)            {                dis[g[i].to] = dis[u] + g[i].w;                if(flag[g[i].to] == false)                {                    flag[g[i].to] = true;                    que[rear ++] = g[i].to;                    if(rear == M)                        rear = 0;                }            }        }    }}int main(){    int i,a,b,t,cas = 0;    int level;    scanf("%d",&t);    while(t --)    {        scanf("%d%d%d",&n,&m,&c);        memset(head,-1,sizeof(head));        num = 0;        for(i = 1;i < n;i ++)        {            build(n + i + 1,n + n + i,c);            build(n + i,n + n + i + 1,c);        }        for(i = 1;i <= n;i ++)        {            dis[i] = dis[i + n] = dis[i + n + n] = inf;            flag[i] = flag[i + n] = flag[i + n + n] = false;            scanf("%d",&level);            build(i,n + level,0);            build(n + n + level,i,0);        }        for(i = 1;i <= m;i ++)        {            scanf("%d%d%d",&a,&b,&level);            build(a,b,level);            build(b,a,level);        }        printf("Case #%d: ",++cas);        SPFA();        if(dis[n] == inf || n == 0)            dis[n] = -1;        printf("%d\n",dis[n]);    }    return 0;}//906MS13856K//750MS13856K//796MS13856K`