P1608 路径统计

/*
最短路计数 if dis==dis+w  cnt[v]+=vnt[u]  else cnt=cnt
 
*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
//#include<queue>
//#include<vector>
#include<bits/stdc++.h>
#define ll long long
#define ddd printf("-----------------------\n");
using namespace std;
const int maxn=2e3+10 ;

int n,e;
int head[maxn],to[maxn*maxn],nxt[maxn*maxn],w[maxn*maxn],tot,chong[maxn][maxn];
int dis[maxn],vis[maxn],cnt[maxn];

void add(int u,int v,int val){
    to[++tot]=v,nxt[tot]=head[u],head[u]=tot,w[tot]=val;
}

void dij()
{
    memset(dis,0x3f3f3f3f,sizeof(dis));
    cnt[1]=1;
    
    priority_queue<pair<int,int>> q;
    q.push(make_pair(0,1)),dis[1]=0;
    
    while(!q.empty())
    {
        int u=q.top().second;q.pop();
        if(vis[u]) continue; vis[u]=1;
        for(int i=head[u];i;i=nxt[i])
        {
            int v=to[i];
            if(dis[v]>dis[u]+w[i])
            {
                dis[v]=dis[u]+w[i];
                cnt[v]=cnt[u];
                q.push(make_pair(-dis[v],v));
            }
            else if(dis[v]==dis[u]+w[i]) cnt[v]+=cnt[u];
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>e;
    for(int i=1;i<=e;i++){
        int a,b,val;cin>>a>>b>>val;
        
        if(chong[a][b]==0)
        {
            chong[a][b]=val;
            add(a,b,val);    
        }
        else{
            for(int i=head[a];i;i=nxt[i]){
                int v=to[i];
                if(v==b) w[i]=min(w[i],val);
            }
        }
    }
    
    dij();
    
    if(dis[n]==0x3f3f3f3f) cout<<"No answer\n";
    else cout<<dis[n]<<" "<<cnt[n]<<'\n';
    
    return 0;
}

 

posted @ 2023-09-17 16:05  JMXZ  阅读(10)  评论(0)    收藏  举报