spfa+dp(洛谷1144 最短路计数)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spfa+dp(洛谷1144 最短路计数)相关的知识,希望对你有一定的参考价值。
给出一个N个顶点M条边的无向无权图,顶点编号为1~N。问从顶点1开始,到其他每个点的最短路有几条。
输入格式:
输入第一行包含2个正整数N,M,为图的顶点数与边数。
接下来M行,每行两个正整数x, y,表示有一条顶点x连向顶点y的边,请注意可能有自环与重边。
输出格式:
输出包括N行,每行一个非负整数,第i行输出从顶点1到顶点i有多少条不同的最短路,由于答案有可能会很大,你只需要输出mod 100003后的结果即可。如果无法到达顶点i则输出0。
输入样例#1:
5 7 1 2 1 3 2 4 3 4 2 3 4 5 4 5
输出样例#1:
1 1 1 2 4
讲一下思路吧,跑一遍spfa,由于每条边的权值为1,所以第一次遍历到的点的权值肯定是最小的。然后运用dp的思想,每次遍历到的点的方案数等于前面的方案数之和,于是数组开大点就能a了。原谅我写dp是看题解大神的~
这次我的代码应该比较清晰~
#include<bits/stdc++.h> #define maxn 3000000 #define maxm 3000000 #define inf 129302101 using namespace std; struct Edge { int to,next,w; }; int n,m; struct Edge edge[maxm]; int head[maxn],book[maxn],dis[maxn]; int dp[maxn]; int cnt=0; void add(int u,int v,int w) { edge[++cnt].to=v; edge[cnt].next=head[u]; edge[cnt].w=w; head[u]=cnt; } void spfa() { queue<int> q; memset(book,0,sizeof(book)); q.push(1); for(int i=1;i<=m;i++) dis[i]=inf; dis[1]=1; dp[1]=1; book[1]=1; int ans=0; while(!q.empty()) { int j=q.front();q.pop(); for(int i=head[j];i;i=edge[i].next) { int v=edge[i].to; if(!book[v]) { book[v]=1; dis[v]=min(dis[v],dis[j]+1); dp[v]+=dp[j]%100003; q.push(v); } else if(dis[v]==dis[j]+1) dp[v]+=dp[j]%100003; } } } int main() { cin>>n>>m; int u,v; for(int i=1;i<=m;i++) { cin>>u>>v; add(u,v,1); add(v,u,1); } spfa(); for(int i=1;i<=n;i++) cout<<dp[i]%100003<<endl; return 0; }
以上是关于spfa+dp(洛谷1144 最短路计数)的主要内容,如果未能解决你的问题,请参考以下文章