【洛谷P1144】最短路计数
不错的数字
1144 代表着新新志志()
主要是要强调一种思想 也就是我们如果看到疑似在最短路里跑DP的题目
那么 就在spfa/dijkstra里面加状态转移
下面直接看题
P1144 最短路计数
题目描述
给出一个 \(N\) 个顶点 \(M\) 条边的无向无权图,顶点编号为 \(1\sim N\)。问从顶点 \(1\) 开始,到其他每个点的最短路有几条。
输入格式
第一行包含 \(2\) 个正整数 \(N,M\),为图的顶点数与边数。
接下来 \(M\) 行,每行 \(2\) 个正整数 \(x,y\),表示有一条连接顶点 \(x\) 和顶点 \(y\) 的边,请注意可能有自环与重边。
输出格式
共 \(N\) 行,每行一个非负整数,第 \(i\) 行输出从顶点 \(1\) 到顶点 \(i\) 有多少条不同的最短路,由于答案有可能会很大,你只需要输出 $ ans \bmod 100003$ 后的结果即可。如果无法到达顶点 \(i\) 则输出 \(0\)。
输入输出样例 #1
输入 #1
5 7
1 2
1 3
2 4
3 4
2 3
4 5
4 5
输出 #1
1
1
1
2
4
说明/提示
\(1\) 到 \(5\) 的最短路有 \(4\) 条,分别为 \(2\) 条 \(1\to 2\to 4\to 5\) 和 \(2\) 条 \(1\to 3\to 4\to 5\)(由于 \(4\to 5\) 的边有 \(2\) 条)。
对于 \(20\%\) 的数据,\(1\le N \le 100\);
对于 \(60\%\) 的数据,\(1\le N \le 10^3\);
对于 \(100\%\) 的数据,\(1\le N\le10^6\),\(1\le M\le 2\times 10^6\)。
Solution
很明显就是算一个ans数组
然后当最短路更新的时候 更新ans数组
当刚好又遍历到一次最短路的时候 直接加
下面看代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,m,tot;
int x,y;
int head[5000005],ver[5000005],nex[5000005];
ll ans[1000005];
int d[1000005],v[1000005];
queue<int>q;
void add(int x,int y){
ver[++tot]=y;
nex[tot]=head[x];
head[x]=tot;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d%d",&x,&y);
add(x,y);add(y,x);
}
memset(d,0x3f,sizeof(d));
memset(v,0,sizeof(v));
q.push(1);d[1]=0;
v[1]=1;
ans[1]=1;
while(!q.empty()){
int x=q.front();q.pop();
v[x]=0;
for(int i=head[x];i;i=nex[i]){
int y=ver[i];
if(d[y]>d[x]+1){
d[y]=d[x]+1;
ans[y]=ans[x];
if(!v[y]){
v[y]=1;
q.push(y);
}
}
else if(d[y]==d[x]+1){
ans[y]+=ans[x];
ans[y]%=100003;
}
}
}
for(int i=1;i<=n;i++){
cout<<ans[i]<<endl;
}
system("pause");
return 0;
}
//边权都为1的话 那么?
//跑spfa?

浙公网安备 33010602011771号