2 条题解

  • 0
    @ 2026-6-18 0:25:28

    有边权的无向图,求最短路径树的方案数

    思路

    同样的思路,用 cnt[v] 记录节点的最短路方案数,最后乘起来就行了

    
    
    // 最短路径树 Dijkstra 算法 O(MlogN)
    #include<bits/stdc++.h>
    #define ll long long
    #define pli pair<ll,int>
    using namespace std;
    
    const int N=1010,M=N*N;
    const ll mod=2147483647;
    int h[N],to[M],ne[M],idx; ll ww[M];
    void add(int a,int b,ll c){
      to[++idx]=b,ww[idx]=c,ne[idx]=h[a],h[a]=idx;
    }
    int n,m;
    ll d[N],cnt[N]; bool vis[N];
    
    void dijkstra(){
      for(int i=1; i<=n; i++) d[i]=1e18; d[1]=0;
      priority_queue<pli,vector<pli>,greater<pli> >q;
      q.push({0,1});
      while(!q.empty()){
        auto u=q.top().second; q.pop();
        if(vis[u]) continue; vis[u]=1;
        for(int i=h[u]; i; i=ne[i]){
          int v=to[i],w=ww[i];
          if(d[v]>d[u]+w){
            d[v]=d[u]+w;
            q.push({d[v],v});
            cnt[v]=1;
          }
          else if(d[v]==d[u]+w) cnt[v]++;
        }
      }
    }
    int main(){
      scanf("%d%d",&n,&m);
      for(int i=0; i<m; i++){
        int a,b; ll c;
        scanf("%d%d%lld",&a,&b,&c);
        add(a,b,c),add(b,a,c);
      }
      dijkstra();
      ll ans=1;
      for(int i=2; i<=n; i++) ans=ans*cnt[i]%mod;
      printf("%lld\n",ans);
    }
    
    • 0
      @ 2026-2-6 14:41:32
      //堆优化dijkstra153ms:
      #include<bits/stdc++.h>
      using namespace std;
      typedef long long LL;
      typedef pair<int,int> PII; 
      const int N=1010;
      const LL P=(1ll<<31)-1;
      vector<PII>G[N];
      int n,m,d[N],vis[N],sum[N];
      void dijkstra()
      {
          priority_queue<PII,vector<PII>,greater<PII>>q;
          memset(d,63,sizeof(d));d[1]=0;
          memset(vis,0,sizeof(vis));
          q.push({0,1});
          while(!q.empty())
      	{
              int x=q.top().second;q.pop();
      		if(vis[x])continue;
      		vis[x]=1;
              for(auto i:G[x])
      		{
                  int y=i.first,w=i.second;
                  if(d[y]>d[x]+w)
      			{
                      d[y]=d[x]+w;
                      q.push({d[y],y});
                  }
              }
          }   
      }
      int main()
      {
          scanf("%d%d",&n,&m);
          for(int i=1,x,y,w;i<=m;i++)
      	{
              scanf("%d%d%d",&x,&y,&w);
              G[x].emplace_back(PII(y,w));
              G[y].emplace_back(PII(x,w));
          }
          dijkstra();
          memset(sum,0,sizeof(sum));
          for(int x=1;x<=n;x++)
      	{
              for(auto i:G[x])
      		{
                  int y=i.first,w=i.second;
                  if(d[x]+w==d[y])sum[y]++;
              }
          }
          LL ans=1;
          for(int i=2;i<=n;i++)ans=ans*sum[i]%P;
          printf("%lld",ans);
          return 0;
      }
      
      //spfa163ms:
      #include<bits/stdc++.h>
      using namespace std;
      typedef long long LL;
      typedef pair<int,int> PII; 
      const int N=1010;
      const LL P=(1ll<<31)-1;
      vector<PII>G[N];
      int n,m,d[N],vis[N],sum[N];
      void spfa()
      {
          priority_queue<PII,vector<PII>,greater<PII>>q;
          memset(d,63,sizeof(d));d[1]=0;
          memset(vis,0,sizeof(vis));vis[1]=1;
          q.push({0,1});
          while(!q.empty())
      	{
              int x=q.top().second;q.pop();vis[x]=0;
              for(auto i:G[x])
      		{
                  int y=i.first,w=i.second;
                  if(d[y]>d[x]+w)
      			{
                      d[y]=d[x]+w;
                      if(!vis[y])q.push({d[y],y}),vis[y]=1;
                  }
              }
          }   
      }
      int main()
      {
          scanf("%d%d",&n,&m);
          for(int i=1,x,y,w;i<=m;i++)
      	{
              scanf("%d%d%d",&x,&y,&w);
              G[x].emplace_back(PII(y,w));
              G[y].emplace_back(PII(x,w));
          }
          spfa();
          memset(sum,0,sizeof(sum));
          for(int x=1;x<=n;x++)
      	{
              for(auto i:G[x])
      		{
                  int y=i.first,w=i.second;
                  if(d[x]+w==d[y])sum[y]++;
              }
          }
          LL ans=1;
          for(int i=2;i<=n;i++)ans=ans*sum[i]%P;
          printf("%lld",ans);
          return 0;
      }
      
      • 1

      D94【最短路】单源最短路等价子图个数 黑暗城堡(题意错误,待修改)

      信息

      ID
      1437
      时间
      500ms
      内存
      64MiB
      难度
      8
      标签
      递交数
      144
      已通过
      25
      上传者