题目描述
求一个图关于1的最小路径树的方案数
解析
想复杂了qwq
跑dij的时候如果dis[now]+w==dis[to],就使cnt[to]++
如果更新dis,cnt赋值成1
最后乘起来即可
本题可以这样应该是因为由于边权均正,所以所有点的选取方案是独立的
所以直接上乘法即可
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define il inline
const int N=1e6+100;
const int M=150;
const int mod=2147483647;
const double eps=1e-6;
inline ll read(){ll x=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}while(isdigit(c)){x=x*10+c-'0';c=getchar();}return x*f;
}
int n,m;
struct node{int to,nxt,w;
}p[N];
int fi[N],cnt;
void addline(int x,int y,int w){p[++cnt]=(node){y,fi[x],w};fi[x]=cnt;return;
}
int dis[N],num[N];
typedef pair<int,int> pr;
#define mkp make_pair
priority_queue<pr,vector<pr>,greater<pr> >q;
bool vis[N];
void dij(){memset(dis,0x3f,sizeof(dis));dis[1]=0;q.push(mkp(0,1));while(!q.empty()){int now=q.top().second;q.pop();if(vis[now]) continue;vis[now]=1;for(int i=fi[now];~i;i=p[i].nxt){int to=p[i].to;if(dis[to]>dis[now]+p[i].w){dis[to]=dis[now]+p[i].w;num[to]=1;q.push(mkp(dis[to],to));}else if(dis[to]==dis[now]+p[i].w) num[to]++;}}
}
int main(){memset(fi,-1,sizeof(fi));cnt=-1;n=read();m=read();for(int i=1;i<=m;i++){int x=read(),y=read(),z=read();addline(x,y,z);addline(y,x,z);}dij();ll ans=1;for(int i=2;i<=n;i++) (ans*=num[i])%=mod;printf("%lld\n",ans);return 0;
}
/*
4
5 3 3 1
9
5 5 5 2 2 2 1 1 1
*/