题目描述
给出一个N个顶点MM条边的无向无权图,顶点编号为1−N。问从顶点11开始,到其他每个点的最短路有几条。
输入格式
第一行包含2个正整数N,M,为图的顶点数与边数。
接下来M行,每行2个正整数x,y,表示有一条顶点x连向顶点y的边,请注意可能有自环与重边。
输出格式
共N行,每行一个非负整数,第i行输出从顶点1到顶点i有多少条不同的最短路,由于答案有可能会很大,你只需要输出ans mod100003后的结果即可。如果无法到达顶点i则输出0。
题解:
很简单的最短路计数,只需要松弛的时候判断一下能不能由某个点转化过来即可,可以的话就加上这个点的最短路条数,最后直接输出即可
AC代码(SPFA):
#pragma GCC optimize(2)
#include
#include
using namespace std;
using namespace __gnu_cxx;
#define LL long long
const int MAXN = 1e6+50;
const int MOD = 1e9+7;
const int INF = 1e9;
struct node{ int v,nxt; }edge[MAXN<<2];
int head[MAXN],vis[MAXN],dis[MAXN],res[MAXN],tot,n,m;
inline void add(int u,int v){
edge[++tot].v=v; edge[tot].nxt=head[u]; head[u]=tot;
edge[++tot].v=u; edge[tot].nxt=head[v]; head[v]=tot;
}
inline void SPFA(){
for(int i=1;i<=n;i++) dis[i]=INF,vis[i]=0;
dis[1]=0,vis[1]=1,res[1]=1;
queue<int> que; que.push(1);
while(!que.empty()){
int u=que.front(); que.pop();
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].v;
if(dis[v]>dis[u]+1){
dis[v]=dis[u]+1; res[v]=res[u];
if(!vis[v]) vis[v]=1,que.push(v);
}else if(dis[v]==dis[u]+1){
res[v]=(res[v]+res[u])%100003;
}
}
}
}
signed main(){
scanf("%d%d",&n,&m);
for(int i=1,u,v;i<=m;i++) scanf("%d%d",&u,&v),add(u,v);
SPFA();
for(int i=1;i<=n;i++) printf("%d\n",res[i]);
return 0;
}
AC代码(Dijkstra):
#pragma GCC optimize(2)
#include
#include
using namespace std;
using namespace __gnu_cxx;
#define LL long long
const int MAXN = 1e6+50;
const int MOD = 1e9+7;
const int INF = 1e9;
struct node{ int v,nxt; }edge[MAXN<<2];
int head[MAXN],vis[MAXN],dis[MAXN],res[MAXN],tot,n,m;
inline void add(int u,int v){
edge[++tot].v=v; edge[tot].nxt=head[u]; head[u]=tot;
edge[++tot].v=u; edge[tot].nxt=head[v]; head[v]=tot;
}
inline void dijkstra(){
for(int i=1;i<=n;i++) dis[i]=INF;
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > que;
que.push(make_pair(0,1)); dis[1]=0,res[1]=1;
while(!que.empty()){
int u=que.top().second; que.pop();
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].v;
if(dis[v]>dis[u]+1){
dis[v]=dis[u]+1; res[v]=res[u];
que.push(make_pair(dis[v],v));
}else if(dis[v]==dis[u]+1){
res[v]=(res[v]+res[u])%100003;
}
}
}
}
signed main(){
scanf("%d%d",&n,&m);
for(int i=1,u,v;i<=m;i++) scanf("%d%d",&u,&v),add(u,v);
dijkstra();
for(int i=1;i<=n;i++) printf("%d\n",res[i]);
return 0;
}