//无向图版本
struct Edge
{
int to;
int w;
};
struct node
{
int v;
int dist;
int mark;
bool friend operator <(const node &a,const node &b)
{
if(a.dist!=b.dist)
return a.dist>b.dist;
return a.v>b.v;
}
};
priority_queue<node> Q;
vector<Edge>gra[N];
int dp[N][3];//1是最短路条数;2是次短路条数
int vis[N][3];
int dis[N][3];//1是最短路的长度;2是次短路的长度
int n,m;
void init()
{
for(int i=0; i<N; i++)
{
dp[i][1]=dp[i][2]=0;
vis[i][1]=vis[i][2]=0;
dis[i][1]=dis[i][2]=INF;
}
}
void addedge(int u,int v,int w)
{
gra[u].push_back((Edge){v,w});
gra[v].push_back((Edge){u,w});
}
void Dijstra(int st,int ed)
{
dis[st][1]=0;
dp[st][1]=1;
node q,p;
p.dist=0;
p.mark=1;
p.v=st;
Q.push(p);
while(!Q.empty())
{
q=Q.top();
Q.pop();
if(vis[q.v][q.mark])
continue;
vis[q.v][q.mark]=1;
for(int i=0; i<(int)gra[q.v].size(); i++)
{
int vv=gra[q.v][i].to;
ll ww=gra[q.v][i].w;
if(!vis[vv][1]&&dis[vv][1]>q.dist+ww)//比最短路短,更新最短路
{
if(dis[vv][1]!=INF)
{
dis[vv][2]=dis[vv][1];
dp[vv][2]=dp[vv][1];
p.dist=dis[vv][2];
p.mark=2;
p.v=vv;
Q.push(p);
}
dis[vv][1]=q.dist+ww;
dp[vv][1]=dp[q.v][q.mark];
p.mark=1;
p.dist=dis[vv][1];
p.v=vv;
Q.push(p);
}
else if(!vis[vv][1]&&dis[vv][1]==q.dist+ww)//等于最短路,更新条数
{
dp[vv][1]+=dp[q.v][q.mark];
}
else if(!vis[vv][2]&&dis[vv][2]>q.dist+ww)//比次短路短,更新次短路
{
dis[vv][2]=q.dist+ww;
dp[vv][2]=dp[q.v][q.mark];
p.mark=2;
p.dist=dis[vv][2];
p.v=vv;
Q.push(p);
}
else if(!vis[vv][2]&&dis[vv][2]==q.dist+ww)//等于次短路,更新条数
{
dp[vv][2]+=dp[q.v][q.mark];
}
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
init();
for(int i=0;i<N;i++)
gra[i].clear();
scanf("%d%d",&n,&m);//n个点;m条边
int u,v,w;
for(int i=0; i<m; i++)
{
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
}
Dijstra(1,n);//1到n的最短路
}
return 0;
}
参考例题:
HDU6181(无向图),HDU3191( 有向图)