zoukankan      html  css  js  c++  java
  • 【u116】最短路计数

    Time Limit: 1 second
    Memory Limit: 128 MB

    【问题描述】

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

    【输入格式】

    输入文件shortest.in的第一行包含2个正整数N,M,为图的顶点数与边数。 接下来M行,每行两个正整数x, y,表示有一条顶点x连向顶点y的边,请注意可能有自环与重边。
    【输出格式】

    输出文件shortest.out包括N行,每行一个非负整数,第i行输出从顶点1到顶点i有多少条不同的最短路,由于答案有可能会很大,你只需要输出mod 100003后的结果即可。如果无法到达顶点i则输出0。

    【数据规模】

    对于20%的数据,N ≤ 100; 对于60%的数据,N ≤ 1000; 对于100%的数据,N ≤ 100000,M ≤ 200000。

    Sample Input1

    5 7
    1 2
    1 3
    2 4
    3 4
    2 3
    4 5
    4 5

    Sample Output1

    1
    1
    1
    2
    4

    【样例说明】

    1到5的最短路有4条,分别为2条1-2-4-5和2条1-3-4-5(由于4-5的边有2条)。
    【题目链接】:http://noi.qz5z.com/viewtask.asp?id=u116

    【题解】

    自环直接删掉,因为它只会增加长度;
    设dis[x]表示从1号节点到x号节点的最短路;
    因为是无权图;所以在进行bfs的时候第一次到达的点就是最短路;
    且在进行bfs的时候队列中从头节点到尾节点,里面所包含的节点的dis值肯定是不下降的;则我们处理到第x号节点,要找它的出度的时候;所有到x号节点的最短路径一定已经搞出来了;则用ans数组统计到某个点的路径数;在搞出度的时候往后传递就好;
    不会出现x->y处理完之后又出现w->x的情况
    即x的方案数传递给y之后,发现又有到x的最短路的方案;
    这种情况是不会出现的;(还是那个dis数组是不下降的原因);
    这里写图片描述
    即ans[y] +=ans[x]之后,不可能会有一个节点w又更新了ans[x];因为广搜是一步一步地处理的;
    假设dis[x]==3;
    则我们如果要更新y号节点的方案数肯定是因为我们当前队列的头结点x已经是dis值最小的点了;
    而dis[w]要想更新dis[x];则dis[w]肯定小于3;则肯定在取出当前头结点x之前w已经更新过x了;

    【完整代码】

    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <set>
    #include <map>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <stack>
    #include <string>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    void rel(LL &r)
    {
        r = 0;
        char t = getchar();
        while (!isdigit(t) && t!='-') t = getchar();
        LL sign = 1;
        if (t == '-')sign = -1;
        while (!isdigit(t)) t = getchar();
        while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
        r = r*sign;
    }
    
    void rei(int &r)
    {
        r = 0;
        char t = getchar();
        while (!isdigit(t)&&t!='-') t = getchar();
        int sign = 1;
        if (t == '-')sign = -1;
        while (!isdigit(t)) t = getchar();
        while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
        r = r*sign;
    }
    
    const int INF = 0x3f3f3f3f;
    const int MOD = 100003;
    const int MAXN = 1e5+100;
    const int MAXM = 40e4+100;
    const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
    const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
    const double pi = acos(-1.0);
    
    int n,m,nex[MAXM],fir[MAXN],en[MAXM];
    queue <int> dl;
    int dis[MAXN],ans[MAXN];
    int totm = 0;
    
    void add(int x,int y)
    {
        totm++;
        nex[totm] = fir[x];
        fir[x] = totm;
        en[totm] = y;
    }
    
    int main()
    {
        //freopen("F:\rush.txt","r",stdin);
        rei(n);rei(m);
        rep1(i,1,m)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            if (x!=y)
                add(x,y),add(y,x);
        }
        dl.push(1);
        memset(dis,INF,sizeof dis);
        ans[1] = 1;dis[1] = 0;
        while (!dl.empty())
        {
            int x = dl.front();
            dl.pop();
            for (int temp=fir[x];temp;temp=nex[temp])
            {
                int y = en[temp];
                if (dis[y]==INF)
                {
                    dis[y] = dis[x]+1;
                    ans[y] = ans[x];
                    dl.push(y);
                }
                else
                    if (dis[y]==dis[x]+1)
                        ans[y] = (ans[y]+ans[x])%MOD;
            }
        }
        rep1(i,1,n)
            printf("%d
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    HDU 1434 幸福列车(优先队列)
    HDU 4287 Intelligent IME(字典树)
    HDU 1671 Phone List(字典树)
    HDU 1711 Number Sequence(KMP匹配数字串)
    HDU 1251 统计难题(字典树计算前缀数量)
    HDU 2087 剪花布条(KMP基础应用)
    HRBUST 1909 理工门外的树(双数组实现线段树功能)
    HDU 1166 敌兵布阵(线段树)
    HDU 1754 I Hate It(线段树基础应用)
    HDU 1260 Tickets(基础dp)
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626913.html
Copyright © 2011-2022 走看看