P1144 最短路计数(SPFA/Dijkstra)

题目描述
给出一个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;
} 

你可能感兴趣的:(最短路,最短路)