博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Luogu P1144 最短路计数 【最短路】 By cellur925
阅读量:5148 次
发布时间:2019-06-13

本文共 3016 字,大约阅读时间需要 10 分钟。

常规的最短路计数问题:注意有重边(重边不用理,看样例),自环(读入时过滤)。

另外这个无向图没有权,其实可以直接bfs做,但考虑到以后带权的情况,按spfa走了。

水题被卡了三次(嘤嘤嘤

 

第一次40pts:忘取膜了(???

第二次80pts:加了多余的判断,实质还是思路不清晰

第三次100pts:去了冗余的判断,终于A了。

 

思路

记录f数组表示f[i]为以i为终点,1为起点的最短路条数。初始只有f[1]=1。

其余在松弛的时候如果更新,f[v]=f[u];

如果恰好相等(有相同最短路径)(这种情况不能和上面的情况一起判断),就f[v]+=f[u]

Code

1 #include
2 #include
3 #include
4 #include
5 #include
6 using namespace std; 7 const int inf=2147483647; 8 int n,m,s; 9 int p=100003;10 int num;11 int pre[1000090],f[1000090];12 struct node{13 int to,val,next;14 }edge[4000090];15 int dis[1000090];16 bool visit[1000090];17 void add(int x,int y,int z)18 {19 num++;20 edge[num].val=z;21 edge[num].to=y;22 edge[num].next=pre[x];23 pre[x]=num;24 }25 void spfa()26 {27 queue
q;28 for(int i=1;i<=n;i++)29 dis[i]=inf;30 q.push(1);31 dis[1]=0;f[1]=1;32 visit[1]=1;33 while(!q.empty())34 {35 int u=q.front();36 q.pop();37 visit[u]=0;38 for(int i=pre[u];i>0;i=edge[i].next)39 {40 int v=edge[i].to;41 //if(u==1) (f[v]=1)%=p;42 if(dis[v]>dis[u]+edge[i].val)43 {44 dis[v]=dis[u]+edge[i].val;45 /*if(u!=1)*/ (f[v]=f[u])%=p;46 if(visit[v]==0)47 {48 visit[v]=1;49 q.push(v);50 }51 }52 else if(dis[v]==dis[u]+edge[i].val)53 (f[v]+=f[u])%=p; 54 }55 }56 }57 int main()58 {59 scanf("%d%d",&n,&m);60 for(int i=1;i<=m;i++)61 {62 int x=0,y=0,z=0;63 scanf("%d%d",&x,&y);64 if(x==y) continue;65 add(x,y,1);66 add(y,x,1); 67 }68 spfa();69 for(int i=1;i<=n;i++)70 printf("%d\n",f[i]);71 return 0;72 }
View Code

 * Update 2018.9.22

做NOIp2017逛公园的时候发现自己的最短路计数算法有些Bug==

导致30分没有成功拿到。

做了一道加强版的最短路计数 

1 #include
2 #include
3 #include
4 #include
5 6 using namespace std; 7 typedef long long ll; 8 9 int n,m,fake;10 int vis[2090],dis[2090];11 ll f[2090];12 int e[2090][2090];13 14 void spfa()15 {16 memset(dis,63,sizeof(dis));17 fake=dis[233];18 queue
q;19 q.push(1);vis[1]=1;dis[1]=0;f[1]=1;20 while(!q.empty())21 {22 int u=q.front();q.pop();23 vis[u]=0;24 if(u==n) continue;25 for(int i=1;i<=n;i++)26 {27 if(dis[i]==dis[u]+e[u][i])28 f[i]+=f[u];29 if(dis[i]>dis[u]+e[u][i])30 {31 dis[i]=dis[u]+e[u][i];32 f[i]=f[u];33 }34 if(f[i]&&!vis[i]) vis[i]=1,q.push(i); 35 }36 f[u]=0;37 }38 }39 40 int main()41 {42 scanf("%d%d",&n,&m);43 memset(e,63,sizeof(e));44 for(int i=1;i<=m;i++)45 {46 int x=0,y=0,z=0;47 scanf("%d%d%d",&x,&y,&z);48 e[x][y]=min(e[x][y],z);49 }50 spfa();51 if(fake==dis[n]) printf("No answer");52 else printf("%d %lld",dis[n],f[n]);53 return 0;54 }
View Code

还是用这个吧qwq

转载于:https://www.cnblogs.com/nopartyfoucaodong/p/9493584.html

你可能感兴趣的文章
SQL语法(3)
查看>>
在js在添版本号
查看>>
sublime3
查看>>
Exception Type: IntegrityError 数据完整性错误
查看>>
Nuget:Newtonsoft.Json
查看>>
Hdu - 1002 - A + B Problem II
查看>>
每天CookBook之Python-003
查看>>
Android设置Gmail邮箱
查看>>
js编写时间选择框
查看>>
JIRA
查看>>
小技巧——直接在目录中输入cmd然后就打开cmd命令窗口
查看>>
深浅拷贝(十四)
查看>>
HDU 6370(并查集)
查看>>
BZOJ 1207(dp)
查看>>
PE知识复习之PE的导入表
查看>>
HDU 2076 夹角有多大(题目已修改,注意读题)
查看>>
洛谷P3676 小清新数据结构题(动态点分治)
查看>>
九校联考-DL24凉心模拟Day2T1 锻造(forging)
查看>>
Attributes.Add用途与用法
查看>>
L2-001 紧急救援 (dijkstra+dfs回溯路径)
查看>>