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

    P1144 最短路计数

    题目描述

    给出一个(N)个顶点(M)条边的无向无权图,顶点编号为(1-N)。问从顶点(1)开始,到其他每个点的最短路有几条。

    输入格式

    第一行包含(2)个正整数(N,M),为图的顶点数与边数。

    接下来(M)行,每行(2)个正整数(x,y),表示有一条顶点(x)连向顶点(y)的边,请注意可能有自环与重边。

    输出格式

    共NN行,每行一个非负整数,第ii行输出从顶点11到顶点ii有多少条不同的最短路,由于答案有可能会很大,你只需要输出(ans mod 100003)后的结果即可。如果无法到达顶点(i)则输出(0)

    输入输出样例

    输入 #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-2-4-5)(2)(1-3-4-5)(由于(4-5)的边有(2)条)。

    对于(20\%)的数据,(N ≤ 100)

    对于(60\%)的数据,(N ≤ 1000)

    对于(100\%)的数据,(N<=1000000,M<=2000000)

    【思路】

    最短路 , dijkstra

    【题目大意】

    从1到每一个点的最短路有多少条

    【核心思路】

    最短路有多少条?
    完全可以在dijkstra或者SPFA的过程中求出来的
    因为在松弛操作的时候
    用y到x的边去松弛
    如果这条边替换上去会使1到x的距离更近
    那这个时候x的答案就会变为松到他y的最短路的个数
    如果这条边替换上去和原来一样
    那就是目前看来可以当做最短路
    在x原来最短路个数的基础上加上到点y最短路的个数就可以了

    【完整代码】

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    
    using namespace std;
    
    int read()
    {
    	int sum = 0,fg = 1;
    	char c = getchar();
    	while(c < '0' || c > '9')
    	{
    		if(c == '-')fg = -1;
    		c = getchar();
    	}
    	while(c >= '0' && c <= '9')
    	{
    		sum = sum * 10 + c - '0';
    		c = getchar();
    	}
    	return sum * fg;
    }
    const int Max = 2000006;
    const int mo = 100003;
    struct node
    {
    	int y,ne;
    }a[Max << 1];
    int head[Max >> 1],sum = 0;
    
    void add(int x,int y)
    {
    	a[++ sum].y = y;
    	a[sum].ne = head[x];
    	head[x] = sum;
    }
    
    struct point
    {
    	int x;
    	int w;
    	bool operator < (const point xx) const
    	{
    		return xx.w < w;
    	}
    };
    int dis[Max >> 1];
    priority_queue<point>q;
    int ans[Max >> 1];
    bool use[Max >> 1];
    void dj()
    {
    	memset(dis,0x3f,sizeof(dis));
    	dis[1] = 0;
    	ans[1] = 1;
    	q.push((point){1,0});
    	while(!q.empty())
    	{
    		point qwq = q.top();
    		q.pop();
    		int x = qwq.x,w = qwq.w;
    		if(use[x] == true)
    			continue;
    		else
    			use[x] = true;
    		for(register int i = head[x];i != 0;i = a[i].ne)
    		{
    			int awa = a[i].y;
    			if(dis[awa] > dis[x] + 1)
    			{
    				dis[awa] = dis[x] + 1;
    				ans[awa] = ans[x];
    				if(use[awa] == false)
    					q.push((point){awa,dis[awa]});
    			}
    			else
    			if(dis[awa] == dis[x] + 1)
    			{
    				ans[awa] += ans[x];
    				ans[awa] %= mo;
    			}
    		}
    	}
    }
    
    int main()
    {
    	int n = read(),m = read();
    	for(register int i = 1;i <= m;++ i)
    	{
    		int x = read(),y = read();
    		add(x,y);
    		add(y,x);
    	}
    	dj();
    	for(register int i = 1;i <= n;++ i)
    		cout << ans[i] << endl;
    	return 0;
    }
    
  • 相关阅读:
    085 Maximal Rectangle 最大矩形
    084 Largest Rectangle in Histogram 柱状图中最大的矩形
    083 Remove Duplicates from Sorted List 有序链表中删除重复的结点
    082 Remove Duplicates from Sorted List II 有序的链表删除重复的结点 II
    081 Search in Rotated Sorted Array II 搜索旋转排序数组 ||
    080 Remove Duplicates from Sorted Array II 从排序阵列中删除重复 II
    079 Word Search 单词搜索
    078 Subsets 子集
    bzoj2326: [HNOI2011]数学作业
    bzoj2152: 聪聪可可
  • 原文地址:https://www.cnblogs.com/acioi/p/11812959.html
Copyright © 2011-2022 走看看