AcWing1134 最短路计数(拓扑序)

对于计数问题,如果对于dp,那么只要一路推过来就好。但是图内可能存在环,因此必须要想办法

我们可以发现是,这些环对答案没有影响,其实最短路的计数和dp的计数如出一辙

都是在拓扑序上进行。因此我们可以在端点往外bfs或者迪杰斯特拉,这样就能产生拓扑树

而答案就是这样更新而来。如果图中有负权,那么用spfa,但是spfa不是天生满足拓扑序,还需要做一些处理

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=4e5+10;
const int mod=100003;
int h[N],ne[N],e[N],cnt[N],idx;
int dis[N];
int n,m;
void add(int a,int b){
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void bfs(){
    memset(dis,0x3f,sizeof dis);
    queue<int> q;
    q.push(1);
    cnt[1]=1;
    dis[1]=0;
    while(q.size()){
        int t=q.front();
        q.pop();
        int i;
        for(i=h[t];i!=-1;i=ne[i]){
            int j=e[i];
            if(dis[j]>dis[t]+1){
                dis[j]=dis[t]+1;
                cnt[j]=cnt[t];
                q.push(j);
            }
            else if(dis[j]==dis[t]+1){
                cnt[j]=(cnt[j]+cnt[t])%mod;
            }
        }
    }
}
int main(){
    cin>>n>>m;
    int i;
    memset(h,-1,sizeof h);
    for(i=1;i<=m;i++){
        int a,b,c;
        cin>>a>>b;
        add(a,b),add(b,a);
    }
    bfs();
    for(i=1;i<=n;i++){
        printf("%d\n",cnt[i]);
    }
}
View Code

 

posted @ 2020-05-03 22:07  朝暮不思  阅读(122)  评论(0编辑  收藏  举报