题意:给一个有向图,问从s到t的 最短路 和 比最短路距离长1的次短路
思路:Dijkstra(不使用heap)
1.每次维护次短路和最短路的长度,与最短路和次短路的条数
最后输出结果的时候判断当前最短路和次短路的长度差是否为1
2.维护方法:
dis[i][0]:到点i的最短路长度 dis[i][1]:到i点的次短路长度
cnt[i][0]:到点i的最短路的路数 cnt[i][1]:到i点的最短路条数
vis表示最短路或次短路是否已经算出
每次找到和当前集合中距离最近的点加入集合
先更新最短路,如果小于原来的路径,将原来的最短路设为次短路,将新加入的点设为最短路
如果和最短路相等,直接将新加入点的方案数累加到原来的方案数中;
如果不能更新最短路,再更新次短路,更新步骤同上
总之 if balala else blala if blala else blala.......
代码如下:
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cassert>
#include <sstream>
#include <numeric>
#include <climits>
#include <string>
#include <cctype>
#include <ctime>
#include <iomanip>
#include <cmath>
#include <vector>
#include <queue>
#include <list>
#include <map>
#include <set>
#define INF 29000
#define MAX 1000000000
using namespace std;
struct data{
int to,len,next;
}bian[2*INF];
int t,size,first[INF],casee;
int vis[INF][2],cnt[INF][2],dis[INF][2];
int n,m,x,y,z,s;
//dis[i][0]:到点i的最短路 dis[i][1]次短路
//cnt[i][0]:到点i的最短路的路数
//vis表示最短路或次短路是否已经算出
void add(int x,int y,int z)
{
size++;
bian[size].next=first[x];
first[x]=size;
bian[size].to=y;
bian[size].len=z;
}
void Dijkstra(int s,int t)
{
dis[s][0]=0;
cnt[s][0]=1;
int maxx,pos,flag;
for(int i=1;i<=2*n-1;i++)
{
int minn=MAX;
for(int j=1;j<=n;j++)
{
if(!vis[j][0]&&minn>dis[j][0])
{
minn=dis[j][0];
pos=j;
flag=0;
}
else
if(!vis[j][1]&&minn>dis[j][1])
{
minn=dis[j][1];
pos=j;
flag=1;
}
}
if(minn==MAX)break;
vis[pos][flag]=1;
for(int u=first[pos];u;u=bian[u].next)
{
int to=bian[u].to,len=bian[u].len;
if(dis[to][0]>minn+len)
{
dis[to][1]=dis[to][0];
dis[to][0]=minn+len;
cnt[to][1]=cnt[to][0];
cnt[to][0]=cnt[pos][flag];
}
else
if(dis[to][0]==minn+len)
cnt[to][0]+=cnt[pos][flag];
else
{
if(dis[to][1]>minn+len)
{
dis[to][1]=minn+len;
cnt[to][1]=cnt[pos][flag];
}
else
if(dis[to][1]==minn+len)
cnt[to][1]+=cnt[pos][flag];
}
}
}
int ans;
if(dis[t][0]+1==dis[t][1])
ans=cnt[t][0]+cnt[t][1];
else ans=cnt[t][0];
cout<<ans<<endl;
}
void init()
{
memset(vis,0,sizeof(vis));
memset(first,0,sizeof(first));
size=0;
for(int i=1;i<=n;i++)
dis[i][0]=dis[i][1]=INF;
memset(cnt,0,sizeof(cnt));
}
int main()
{
// freopen("in.in","r",stdin);
ios::sync_with_stdio(false);cin.tie(NULL);
cin>>casee;
while(casee--)
{
cin>>n>>m;
init();
for(int i=1;i<=m;i++)
{
cin>>x>>y>>z;
add(x,y,z);
}
cin>>s>>t;
Dijkstra(s,t);
}
}