您的位置:首页 > 其它

poj3463 Sightseeing(最短路计数+次短路计数)

2017-11-14 13:10 260 查看
求最短路的个数和比最短路大1的路的个数。可以写堆优化Dijstra,统计最短路个数和次短路个数,然后判断次短路是否是比最短路大1即可。松弛时讨论一下最小和次小的更新。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define pa pair<int,int>
#define N 1010
#define M 10010
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
int tst,n,m,h
,num0=0,dis
,dis1
,num
,num1
;//dis1-次短路
bool inq[N<<1];
struct edge{
int to,next,val;
}data[M];
void Dijstra(int s){
priority_queue<pa,vector<pa>,greater<pa> >q;
memset(inq,0,sizeof(inq));memset(dis,0x3f,sizeof(dis));
dis[s]=0;num[s]=1;q.push(make_pair(dis[s],s));
while(!q.empty()){
int x=q.top().second,w=q.top().first,cnt;q.pop();
if(inq[x]) continue;inq[x]=1;if(x>n) x-=n,cnt=num1[x];else cnt=num[x];
for(int i=h[x];i;i=data[i].next){
int y=data[i].to;
if(dis[y]>w+data[i].val){
dis1[y]=dis[y];num1[y]=num[y];
dis[y]=w+data[i].val;num[y]=cnt;
q.push(make_pair(dis[y],y));
q.push(make_pair(dis1[y],y+n));continue;
}if(dis[y]==w+data[i].val){
num[y]+=cnt;continue;
}if(dis1[y]>w+data[i].val){
dis1[y]=w+data[i].val;num1[y]=cnt;
q.push(make_pair(dis1[y],y+n));continue;
}if(dis1[y]==w+data[i].val){
num1[y]+=cnt;continue;
}
}
}
}
int main(){
//  freopen("a.in","r",stdin);
tst=read();
while(tst--){
n=read();m=read();memset(h,0,sizeof(h));num0=0;
while(m--){
int x=read(),y=read(),val=read();
data[++num0].to=y;data[num0].next=h[x];h[x]=num0;data[num0].val=val;
}int s=read(),t=read();Dijstra(s);if(dis1[t]-1==dis[t]) num[t]+=num1[t];
printf("%d\n",num[t]);
}return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: