洛谷 P1144 最短路计数

本文详细介绍了洛谷P1144最短路计数问题的两种算法实现:SPFA和Dijkstra。通过具体代码示例,展示了如何使用邻接表存储图结构,并运用SPFA算法和Dijkstra算法求解最短路径及其数量。适用于算法学习和竞赛准备。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

洛谷 P1144 最短路计数

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
struct arr{
    int nd,nx,co;
}bot[4000500];
int n,m,cnt;
int dis[1500000],vis[1500000],head[1500000],ans[1500000];
inline int read(){
    int x=0,w=1;char ch;
    while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    if(ch=='-') w=-1,ch=getchar();
    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch-48),ch=getchar();
    return x*w;
}
inline void add(int a,int b) 
{ bot[++cnt].nd=b; bot[cnt].nx=head[a];bot[cnt].co=1; head[a]=cnt; }
inline void spfa(int x) {
    queue<int> q;memset(dis,0x3f,sizeof(dis));
    q.push(x);ans[x]=1; dis[x]=0;
    while(!q.empty()) {
        int u=q.front();q.pop();
        vis[u]=0;
        for(register int i=head[u];i;i=bot[i].nx) {
            int v=bot[i].nd;
            if(dis[v]>dis[u]+bot[i].co) {
                dis[v]=dis[u]+bot[i].co;
                ans[v]=ans[u];
                if(!vis[v]) {
                    vis[v]=1;
                    q.push(v);
                }
            }
            else {
                if(dis[v]==dis[u]+bot[i].co) {
                    ans[v]=(ans[v]+ans[u])%100003;
                }
            }
        }
    }
}
int main(){
    n=read();m=read();
    for(register int i=1;i<=m;++i) {
        int u=read(),v=read();
        add(u,v);add(v,u);
    }
    spfa(1);
    for(register int i=1;i<=n;++i) 
        if(dis[i]==0x3f3f3f3f) cout<<0<<endl;
    else cout<<ans[i]<<endl;
    return 0;
}

加一个用dijstra做的,差不多吧。以NOIP2017day1 t3为例
莫名其妙只能20分,我不知道怎么去弄那个n=100000,k为0的情况。本人用了判重,数组不能开那么大。

#include<bits/stdc++.h>
#include<queue>
#define N 1000100
#define inf 0x3f3f3f3f
using namespace std;
int n,m,head[N],cnt,vis[N],dis[N],ans[N],s=1,ff[2020][2020],k,p;
struct edge{
    int nx,nd,co;
}bot[2*N];
void add(int a,int b,int w){
    bot[++cnt].nx=head[a];  bot[cnt].nd=b; 
	bot[cnt].co=w;  head[a]=cnt;
}
struct node{
    int num,dis;
    bool operator <(const node &s)const{
        return dis>s.dis;
    }
};
inline int read(){
	int x=0,w=1;char ch;
	while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
	if(ch=='-') w=-1,ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch-48),ch=getchar();
	return x*w;
}
inline void init() { cnt=0;memset(head,0,sizeof(head)); memset(ff,0x3f,sizeof(ff));}
void dij(){
    priority_queue<node> q;
    memset(dis,inf,sizeof(dis)); memset(vis,0,sizeof(vis));
    dis[s]=0; q.push((node){s,0});
    while(!q.empty()){
        node uu=q.top(); q.pop();
        if(!vis[uu.num]){
            int u=uu.num;
            vis[u]=1;
            for(int i=head[u];i;i=bot[i].nx){
                int v=bot[i].nd;
                if(dis[v]==dis[u]+bot[i].co) ans[v]+=ans[u];
                if(dis[v]>dis[u]+bot[i].co){
                    dis[v]=dis[u]+bot[i].co;
                    q.push((node){v,dis[v]});
                    ans[v]=ans[u];
                }

            }
        }
    }
}
int main(){
	freopen("zz.in","r",stdin);
	freopen("zz.out","w",stdout);
	int t=read();
	for(register int kk=1;kk<=t;++kk) {
    	cin>>n>>m>>k>>p;init();
    	for(int i=1;i<=m;i++){ 
			int a=read(),b=read(),c=read();
			if(ff[a][b]>c) ff[a][b]=c;
		}
		for(register int i=1;i<=n;++i)
			for(register int j=i+1;j<=n;++j)
				if(i!=j) add(i,j,ff[i][j]),add(j,i,ff[j][i]);
    	ans[1]=1;
    	dij();
    	if(dis[n]==inf) cout<<"-1";
    	else cout<<ans[n]<<endl;
	}
    return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值