最短パス生成ツリー
1973 ワード
最短経路生成木は1本の木で、そのルートノードはSで、この木の上でdijkstraを走るのは原図の上で走るdと全く同じです.この木の生成はdijkstraで理解できる.タグ付けされていないノードごとにdをpriority_Queue,スタックトップxを取り出し,xは先にマークされる.次にxに接続するノードを更新し、d[y]>d[x]+e[k]があれば更新.c,では,yノードとkのエッジを共に所定の最小経路生成ツリーに選択する.yがマークされると、この所定のエッジは、実際の最小パス生成ツリーのエッジとなる.もう一度理解するとdijkstraはpriorityからランダムに見えますqueueでランダムにポイントを取るのは、実際にはそのポイントに原則があります.図を描くと、YYを見るとdijkstraの拡張経路が1本の木であることがわかります(木の特性を満たしていて、1つの点には多くの子供ノードがあり、各点には1人の父親しかいません......)この木を抽出するのが最小経路生成木です
実はこれは難しくありません.ただ、彼はいくつかの結合問題を出すので、概念を明確にしたほうがいいです.
これは最短パスツリーのシナリオ数を求める問題です.
実はこれは難しくありません.ただ、彼はいくつかの結合問題を出すので、概念を明確にしたほうがいいです.
これは最短パスツリーのシナリオ数を求める問題です.
#include
#define inf 1e12;
using namespace std;
int n,m,x,y,z;
long long dis[1010][1010],g[20000],cnt[20000];
bool vis[2000000]={0};
int main()
{
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;i++)
for(int j = 1;j <= n;j++)// 、
{
if(i == j) dis[i][j]=0;
else dis[j][i] = dis[i][j] = inf;
}
for(int i = 1;i <= m;i++)
{
scanf("%d%d%d",&x,&y,&z);
if(dis[x][y] > z)
dis[x][y] = dis[y][x] = z;
}
for(int i = 1;i <= n;i++) g[i]=dis[1][i];
for(int i = 1;i <= n;i++)// 、
{
long long minn = inf;
int u;
for(int j = 1;j <= n;j++)
{
if(!vis[j] && minn > g[j])
{
minn = g[j];
u = j;
}
} //
vis[u] = 1;
for(int j = 1;j <= n;j++)
if(g[j] > dis[u][j] + g[u])
g[j] = g[u] + dis[u][j];
}
long long ans = 1;
for(int i = 1;i <= n;i++)// 、
for(int j = 1;j <= n;j++)
if(i != j && g[j] == g[i] + dis[i][j])
cnt[j]++;
for(int i = 1;i <= n;i++)
{
if(cnt[i] == 0) continue;
ans *= cnt[i];
ans %= 2147483647;
}
printf("%lld
",ans);
}