洛谷P1144 最短路计数(dijkstra)
题目传送门
题目大意
分别求出点\(1\)到点\(1\)~\(i\)的最短路条数(边权为1,输入包括重边和自环)
Solution
最短路计数模板题
因为边权为1,所以其实可以用BFS求最短路。
这里我还是用dijkstra,适用于任意正权图。
自环跳过不建边,因为最短路肯定不会经过自环边。
重边正常建图即可。
#include<bits/stdc++.h>
using namespace std;
#define maxn1 1000005
#define maxn2 4000005
#define INF 0x3f3f3f3f
#define MOD 100003
int n,m;
int head[maxn1],nxt[maxn2],to[maxn2],cnt=0;
int d[maxn1],vis[maxn1],num[maxn1];
template<typename T>void read(T& x){
int f=0;x=0;char ch=getchar();
while(ch<'0'||ch>'9'){f|=(ch=='-');ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+(ch^48);ch=getchar();}
if(f)x=-x;
}
struct node{
int d,x;
node(int d,int x):d(d),x(x){}
bool operator < (const node& a)const{
return d>a.d;
}
};
void add(int u,int v){
nxt[++cnt]=head[u];
to[cnt]=v;
head[u]=cnt;
}
void dij(int s,int t){
d[s]=0;
num[s]=1;
priority_queue<node>q;
q.push(node(0,1));
while(!q.empty()){
node u=q.top();q.pop();
if(vis[u.x])continue;
vis[u.x]=1;
for(int i=head[u.x];i!=-1;i=nxt[i]){
int v=to[i];
if(d[v]>d[u.x]+1){//关键点1
d[v]=d[u.x]+1;
num[v]=num[u.x];
q.push(node(d[v],v));
}
else if(d[v]==d[u.x]+1){//关键点2
num[v]=(num[v]+num[u.x])%MOD;
}
}
}
}
int main(){
read(n),read(m);
int u,v;
memset(head,-1,sizeof(head));
memset(num,0,sizeof(num));
memset(vis,0,sizeof(vis));
memset(d,INF,sizeof(d));
for(int i=1;i<=m;++i){
read(u),read(v);
if(u==v)continue;
add(u,v);
add(v,u);
}
dij(1,n);
for(int i=1;i<=n;++i){
printf("%d\n",num[i]);
}
return 0;
}

浙公网安备 33010602011771号