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

来源:互联网 发布:windows桌面管理工具 编辑:程序博客网 时间:2024/06/05 08:38

求最短路的个数和比最短路大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 10010inline 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[N],num0=0,dis[N],dis1[N],num[N],num1[N];//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;}
原创粉丝点击