洛谷1144 最短路的个数

方法一:这种发放适合于只求最短路的个数,不能用来输出最短路。

我们直接在spfa的过程中使用cnt[]数组记录最短路的个数,用dijkstra也可以!

更新cnt分情况:

 

  1. 如果dis[next]>dis[now]+1
    那么之前到达点next的路>dis[now]+1
    cnt[next]=cnt[now]
  2. 如果dis[next]==dis[now]+1
    那么之前到达点next的路也有距离为dis[now]+1的点。
    cnt[next]+=cnt[now]
#include <bits/stdc++.h> 
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define res register int 
const int maxn=1e6+5;
vector<int> v[maxn];
int dis[maxn],vis[maxn];
int cnt[maxn];
int N,M,mod=100003;


//最短路的个数
void spfa()
{
	memset(dis,inf,sizeof(dis));
	memset(vis,0,sizeof(vis));
	queue<int> q;
	q.push(1);
	vis[1]=1;
	dis[1]=0;
	cnt[1]=1;
	while(!q.empty()){
		int x=q.front();
		q.pop();
		vis[x]=0;
		for(res i=0;i<v[x].size();i++){
			int y=v[x][i];
			if(dis[y]>dis[x]+1){
				dis[y]=dis[x]+1;
				cnt[y]=cnt[x]%mod;
				if(!vis[y]){
					q.push(y);
					vis[y]=1;
				}
			}else if(dis[y]==dis[x]+1){
				cnt[y]+=cnt[x];
				cnt[y]%=mod;
				if(!vis[y]){
					q.push(y);
					vis[y]=1;
				}
			}
		} 
	}
} 

int main()
{
	scanf("%d%d",&N,&M);
	int from,to;
	for(res i=0;i<M;i++){
		scanf("%d%d",&from,&to);
		v[from].push_back(to);
		v[to].push_back(from);
	}
	spfa();
	for(res i=1;i<=N;i++){
		printf("%d",cnt[i]);
		printf("\n");
	}
	return 0;
}





方法二:可以记录路径,但是很慢 

我们可以用vector<int> pre[maxn]记录下每一个节点被最短到达的前一个点的节点序号。因为我们记录的都是前驱,所以我们可以从终点出发。这样遍历到的每一个节点都在最短路上面。然后我们dfs或者bfs,ans+每一个遍历到节点前驱的个数-1。最后输出让ans+1。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值