题目简介
题目描述
给你一个N点M边的有向图,求第一个点到第n个点的最短路和最短路条数
题目分析
很明显直接Dijkstra求最短路,加一个最短路计数
如下:
if(dis[y]>dis[x]+edge[i].w){
dis[y]=dis[x]+edge[i].w;
ans[y]=ans[x];
}
else if(dis[y]==dis[x]+edge[i].w) ans[y]+=ans[x];
记住要删除重边,要不然计数会重复
上代码
#include<bits/stdc++.h>
#define re register
#define ll long long
using namespace std;
inline int read()
{
ll k=1,sum=0;
char c=getchar();
for(;c<'0' || c>'9';c=getchar()) if(c=='-') k=-1;
for(;c>='0' && c<='9';c=getchar()) sum=sum*10+c-'0';
return sum*k;
}
const int N=2e3+10,E=4e6+10;
int n,e;
struct Edge{
int to,nxt,w;
};
Edge edge[E<<1];
const int MOD=100003;
int head[N],cnt;
int dep[N];
int dis[N],ans[N];
bool vis[N];
int awsl[N][N];
struct New{
int x,d;
bool operator<(const New& qwq) const{
return d>qwq.d;
}
};
priority_queue<New> Q;
inline void Add(int x,int y,int w){
edge[++cnt].to=y;
edge[cnt].nxt=head[x];
edge[cnt].w=w;
head[x]=cnt;
}
inline void Dijkstra(){
memset(dis,0x3f3f3f3f,sizeof(dis));
dis[1]=0;ans[1]=1;
Q.push((New){1,0});
while(!Q.empty()){
New fr=Q.top();Q.pop();
int x=fr.x;
if(vis[x]) continue;
vis[x]=1;
for(re int i=head[x];i;i=edge[i].nxt){
int y=edge[i].to;
if(dis[y]>dis[x]+edge[i].w){
dis[y]=dis[x]+edge[i].w;
ans[y]=ans[x];
Q.push((New){y,dis[y]});
}
else if(dis[y]==dis[x]+edge[i].w) ans[y]+=ans[x];
}
}
}
int main()
{
n=read();e=read();
for(re int i=1;i<=e;++i){
int x=read(),y=read(),w=read();
if(!awsl[x][y] || awsl[x][y]>w){
Add(x,y,w);awsl[x][y]=w;
}
}
Dijkstra();
if(ans[n]==0) cout<<"No answer";
else cout<<dis[n]<<" "<<ans[n];
return 0;
}