zoukankan      html  css  js  c++  java
  • 洛谷P1144最短路计数题解

    最短路计数

    此题还是寻找从1到i点总共有几个最短路且每条边的边长为1,对于这种寻找最短路的个数,我们可以反向搜索,即先用(SPFA)预处理出所有点的最短路,然后我们反向记忆化搜索,可以用(sum[i])表示从i到1的最短路个数,然后我们初始化(sum[1] = 1),然后就可以了

    代码:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #define rqy 100003
    using namespace std;
    int n,m,lin[1000100],tot,dis[1000010],sum[1000010]={0,1},vis[1000010];
    queue<int> q;
    struct cym{
    	int to,next;
    }e[1000100];
    void add(int u,int v)
    {
    	e[++tot].to=v;
    	e[tot].next=lin[u];
    	lin[u]=tot;
    }
    int dfs(int u)
    {
    	if(sum[u])
    	return sum[u];
    	for(int i=lin[u];i;i=e[i].next) 
    	  if (dis[u] == dis[e[i].to]+1) // 双向图所以可以反向搜索,说明to是u的上一层节点中的一个,也就是说to比 u 靠近 1 
    	  sum[u]=(sum[u]+dfs(e[i].to))%rqy; 
    	return sum[u];
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	memset(dis,0x3f,sizeof(dis));
    	dis[1]=0;
    	q.push(1);
    	for (int i = 1; i <= m; i++)
    	{
    		int x,y;
    		scanf("%d%d",&x,&y);
    		add(x,y);
    		add(y,x);
    	}
    	while (!q.empty())
    	{
    		int cur=q.front();
    		q.pop();
    		vis[cur]=0;
    		for(int i=lin[cur];i;i=e[i].next)
    		{
    			if(dis[cur]+1<dis[e[i].to])
    			{
    				dis[e[i].to]=dis[cur]+1;
    				if(!vis[e[i].to])
    				{
    					q.push(e[i].to);
    					vis[e[i].to]=1;
    				}
    			}
    		}
    	}
    	for(int i=1;i<=n;i++)
    	printf("%d
    ",dfs(i));
    }
    
  • 相关阅读:
    不可重叠最长重复子串
    离散化
    hash是一门优雅的暴力
    Detect the Virus (字符串转化+AC自动机)
    病毒侵袭(AC自动机变形)
    hdu2069(Coin Change)
    Hie with the Pie(poj3311)
    poj3254(状压dp入门第一道题,很详细)
    map系统学习
    ACM-ICPC 2018 南京赛区网络预赛 B. The writing on the wall
  • 原文地址:https://www.cnblogs.com/liuwenyao/p/9910370.html
Copyright © 2011-2022 走看看