poj3463 sightseeing
难绷。。
最短路变种,其实不难,只是锻炼一下对dijkstra的理解而已。。
但是可是给我锻炼出大问题了啊。。也是好消息吧
这题写完算是真的理解了dijkstra的dp本质。。
有一个我做错了的地方就是我第一次写的代码对于次短路和最短路是不分别的转移的,就是我只是在队列里面记录了我要转移某一个点,而没有记录我要从这个点转移最短路还是次短路。
如果没有计数,这个是对的,但是需要计数,那这个会导致同一条最短路被重复记录,导致答案错误。
然后最蠢的一点是,我第3次把大根堆和小根堆弄混了。
妈妈生的,以后每次用之前都实验。。不然调个两三个小时都可以
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
#define ll long long
using namespace std;
inline int read() {
char c=getchar();int a=0,b=1;
for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1;
for(;c>='0'&&c<='9';c=getchar())a=a*10+c-48;return a*b;
}
int head[200001],tot;
struct edge
{
int next,to,v;
}e[200001];
inline void add(int i,int j,int v)
{
e[++tot].next=head[i];
e[tot].to=j;
e[tot].v=v;
head[i]=tot;
}
int n,m,s,t;
int dist[10001][2],vis[10001][2],cnt[10001][2];
void dijkstra()
{
// memset(dist,0x3f,sizeof(dist));
// memset(vis,0,sizeof(vis));
// memset(cnt,0,sizeof(cnt));
for(int i=1;i<=n;i++)
{
dist[i][0]=dist[i][1]=100000000;
cnt[i][0]=cnt[i][1]=0;
vis[i][0]=vis[i][1]=0;
}
priority_queue<pair<int,pair<int,int> > , vector<pair<int,pair<int,int> > > ,greater<pair<int,pair<int,int> > > > q;
q.push({0,{0,s}});
dist[s][0]=0;
cnt[s][0]=1;
while(!q.empty())
{
int x=q.top().second.second;
int flag=q.top().second.first;
q.pop();
if(vis[x][flag])continue;
vis[x][flag]=1;
for(int i=head[x];i!=0;i=e[i].next)
{
int u=e[i].to;
if(dist[x][flag]+e[i].v<dist[u][0])
{
if(dist[u][0]!=100000000)
{
dist[u][1]=dist[u][0];
cnt[u][1]=cnt[u][0];
q.push({dist[u][1],{1,u}});
}
cnt[u][0]=cnt[x][flag];
dist[u][0]=dist[x][flag]+e[i].v;
q.push({dist[u][0],{0,u}});
}
else
if(dist[x][flag]+e[i].v==dist[u][0])
{
cnt[u][0]+=cnt[x][flag];
}
else
if(dist[x][flag]+e[i].v<dist[u][1])
{
// cout<<u<<' '<<x<<endl;
dist[u][1]=dist[x][flag]+e[i].v;
cnt[u][1]=cnt[x][flag];
q.push({dist[u][1],{1,u}});
}
else
{
// if(flag==1&&u==5&&x==4)cout<<dist[x][flag]<<' '<<e[i].v<<' '<<dist[u][1]<<endl;
if(dist[x][flag]+e[i].v==dist[u][1])
{
cnt[u][1]+=cnt[x][flag];
}
}
}
}
}
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
int T=read();
while(T--)
{
n=read(),m=read();
tot=0;
memset(head,0,sizeof(head));
for(int i=1;i<=m;i++)
{
int x=read(),y=read(),z=read();
add(x,y,z);
}
s=read(),t=read();
dijkstra();
// for(int i=1;i<=n;i++)
// {
// cout<<dist[i][0]<<' ';
// }
// cout<<endl;
// for(int i=1;i<=n;i++)
// {
// cout<<dist[i][1]<<' ';
// }
// cout<<endl;
if(dist[t][0]==dist[t][1]-1)
{
cout<<cnt[t][0]+cnt[t][1]<<endl;
}
else
{
cout<<cnt[t][0]<<endl;
}
}
return 0;
}