(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦
题意:HDU POJ
原题目描述在最下面。
求出最短路和次短路的条数,当次短路比最短路长度小1时,输出条数之和,反之输出最短路条数。
思路:
dis1[],cnt1[],dis2[],cnt2[]
d
i
s
1
[
]
,
c
n
t
1
[
]
,
d
i
s
2
[
]
,
c
n
t
2
[
]
分别表示最短路的长度和条数,次短路的长度和条数。
当当前距离小于当前点最短路长度的时候,更新二者长度和条数。
当当前距离等于当前点最短路长度的时候,更新最短路条数。
当当前距离小于当前点次短路长度的时候,更新次短路的长度和条数。
当当前距离等于当前点次短路长度的时候,更新次短路的条数。
push
p
u
s
h
进队列的时候要标注
push
p
u
s
h
进去的是最短路还是次短路。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<string>
#include<cmath>
#define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) (x)&(-(x))
#define iis std::ios::sync_with_stdio(false)
using namespace std;
typedef long long LL;
const int N = 1005;
const LL INF = 0x3f3f3f3f3f3f3f3f;
struct lp{
int to, id;
LL w;
lp(int a,LL b){to=a;w=b;id=0;}
lp(int a,LL b,int c){to=a;w=b;id=c;}
bool operator <(const lp &a)const {
if(w!=a.w) return w>a.w;
return to>a.to;
}
};
vector<lp>mp[N];
LL dis1[N],dis2[N];
int n, m, pre[N],cnt1[N], cnt2[N], vis[N][3];
int t1,st,ed;
void init(){
for(int i=0;i<=n;++i)mp[i].clear();
}
void dij(){
priority_queue<lp>Q;
Q.push(lp(st,0,1));
memset(cnt1,0,sizeof(cnt1));
memset(cnt2,0,sizeof(cnt2));
memset(vis,0,sizeof(vis));
memset(dis1,0x3f,sizeof(dis1));
memset(dis2,0x3f,sizeof(dis2));
cnt1[st]=1;
dis1[st]=0;
while(!Q.empty()){
lp aa = Q.top();Q.pop();
int u = aa.to, len = mp[u].size();
if(vis[u][aa.id])continue;
vis[u][aa.id] = 1;
for(int i=0;i<len;++i){
int v = mp[u][i].to;
LL w = mp[u][i].w + aa.w;
//printf("*%d %d %lld %lld %d %d\n", u, v, aa.w, w, cnt1[u], cnt2[u]);
if(w<dis1[v]){
dis2[v] = dis1[v];
cnt2[v] = cnt1[v];
dis1[v] = w;
if(aa.id==1)cnt1[v] = cnt1[u];
else cnt1[v] = cnt2[u];
Q.push(lp(v, dis1[v], 1));
Q.push(lp(v, dis2[v], 2));
}else if(w == dis1[v]){
if(aa.id==1)cnt1[v] += cnt1[u];
else cnt1[v] += cnt2[u];
//Q.push(lp(v, dis1[v], 1));
}else if(w < dis2[v]){
dis2[v] = w;
if(aa.id==1)cnt2[v] = cnt1[u];
else cnt2[v] = cnt2[u];
Q.push(lp(v, dis2[v], 2));
}else if(w==dis2[v]){
if(aa.id==1)cnt2[v] += cnt1[u];
else cnt2[v] += cnt2[u];
//Q.push(lp(v, dis2[v], 2));
}
}
}
if(dis1[ed]==dis2[ed]-1)cnt1[ed]+=cnt2[ed];
printf("%d\n", cnt1[ed]);
}
int main(){
int t,a,b;
LL c;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
init();
for(int i=0;i<m;++i){
scanf("%d%d%lld",&a,&b,&c);
mp[a].push_back(lp(b,c));
//mp[b].push_back(lp(a,c));
}
scanf("%d%d", &st,&ed);
dij();
}
return 0;
}