解题思路:这是我从打ACM起做的心态最炸裂的一道题。一开始用A*求K短路写,超内存。然后就老老实实用次短路来写,但为什么我会在这么简单的一道略水的题上卡了半天啊。。。。。可能是我平时一直记忆的模板有问题吧。为什么优先队列中距离相等时,要按标号的顺序排列这一点,我到现在都还是云里雾里的,算了,抽时间换个更加明了的写法吧。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
int map[60][60];
int dis1[60],dis2[60];
int n,m,s,e;
struct node
{
int f,v,d;
node(){}
node(int f,int v,int d):f(f),v(v),d(d){}
}p;
bool operator<(node a,node b)
{
if(a.d!=b.d)
return a.d>b.d;
return a.v>b.v;%不按顺序排列就错
}
priority_queue<node>q;
int record[3][60],vis[3][60];
void djk()
{
int v,f;
node p1;
while(!q.empty()) q.pop();
memset(record,0,sizeof(record));
memset(vis,0,sizeof(vis));
q.push(node(0,s,0));
fill(dis1,dis1+n,inf);
fill(dis2,dis2+n,inf);
dis1[s]=0;
record[0][s]=1;
while(!q.empty())
{
p1=q.top();
v=p1.v;f=p1.f;
q.pop();
if(vis[f][v]) continue;
vis[f][v]=1;
for(int i=0;i<n;i++)
{
//cout<<i<<endl;
if(map[v][i]!=inf&&i!=v)
{
if(!vis[0][i]&&p1.d+map[v][i]<dis1[i])
{
if(dis1[i]!=inf)
{
dis2[i]=dis1[i];
record[1][i]=record[0][i];
q.push(node(1,i,dis2[i]));
}
dis1[i]=p1.d+map[v][i];
record[0][i]=record[f][v];
q.push(node(0,i,dis1[i]));
}else
if(!vis[0][i]&&p1.d+map[v][i]==dis1[i])
{
dis1[i]=p1.d+map[v][i];
record[0][i]+=record[f][v];
}else
if(!vis[1][i]&&p1.d+map[v][i]<dis2[i])
{
dis2[i]=p1.d+map[v][i];
record[1][i]=record[f][v];
q.push(node(1,i,dis2[i]));
}else
if(!vis[1][i]&&p1.d+map[v][i]==dis2[i])
{
record[1][i]+=record[f][v];
}
}
}
}
printf("%d %d\n",dis2[e],record[1][e]);
}
int main()
{
//freopen("t.txt","r",stdin);
int x,y,w;
while(scanf("%d%d%d%d",&n,&m,&s,&e)!=EOF)
{
fill(map[0],map[0]+60*60,inf);
while(m--)
{
scanf("%d%d%d",&x,&y,&w);
map[x][y]=w;
}
djk();
}
return 0;
}