prim的特点是从一个点开始,不断把距离最短的点加入图中,在以此延伸。是一种贪心的想法。当知道prim的特点的时候,就可以想到这题用prim。
这题又要求实际路径=最短路径,,也可以想到用dijkstra。
具体做法:
用dijkstra求出1号犯贱到每个房间的单元最短路。把树形城堡看做以1为根的有根树。
把所有节点按照dis值排序,从小到大一次考虑吧每个节点p加入树形城堡有多少种方法。
和prim类似,维护“最短路径生成树”的一部分记为T
统计有多少个节点x满足,x∈T并且dis[ p ] = dis [ x ] + edge ( x , p ),其中edge表示边的长度。
让p与其中任意一个x项链都符合题目的要求。
根据乘法原理,把每一步统计出的数据乘起来,即可得答案。
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#define mk make_pair
#define ll long long
using namespace std;
inline int read()
{
int sum = 0,p = 1;
char ch = getchar();
while(ch < '0' || ch > '9')
{
if(ch == '-')
p = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9')
{
(sum *= 10) += ch - '0';
ch = getchar();
}
return sum * p;
}
const int M = 5e5 + 10;
const int N = 1e3 + 5;
const int mod = 2147483647;
int n,m;
int head[N],cnt;
struct edge
{
int nxt,to,wei;
}e[M<<1];
priority_queue<pair<int,int> > q;
bool vis[N];
int dis[N],sum[N];
struct pot
{
int id,dis;
}p[N];
void add(int x,int y,int v)//加边
{
e[++cnt].nxt = head[x];
e[cnt].to = y;
e[cnt].wei = v;
head[x] = cnt;
}
void dijkstra()
{
memset(dis,0x3f,sizeof(dis));
dis[1] = 0;
q.push(mk(0,1));
while(q.size())
{
int u = q.top().second;
q.pop();
if(vis[u])
continue;
vis[u] =true;
for(int i = head[u];i;i = e[i].nxt)
{
int v = e[i].to;
if(dis[u] + e[i].wei < dis[v])
{
dis[v] = dis[u] +e[i].wei;
q.push(mk(-dis[v],v));
}
}
}
}
bool cmp(pot a,pot b)
{
return a.dis < b.dis;
}
int main()
{
n = read(),m = read();
for(int i = 1;i <= m;i++)
{
int x = read(),y = read(),l = read();
add(x,y,l);
add(y,x,l);
}
dijkstra();
// for(int i = 1;i <= n;i++)
// printf("%d-===-%d
",i,dis[i]);
// puts("
");
for(int i = 1;i <= n;i++)
{
p[i].id = i;
p[i].dis = dis[i];
}
sort(p+1,p+n+1,cmp);
memset(vis,false,sizeof(vis));
vis[1] = true;
for(int i = 2;i <= n;i++)
{
vis[p[i].id] = true;
for(int j = head[p[i].id];j;j = e[j].nxt)
{
int v = e[j].to;
if(vis[v] && dis[v] + e[j].wei == p[i].dis)
sum[i]++;
}
}
// for(int i = 1;i <= n;i++)
// printf("%d----%d
",i,sum[i]);
ll ans = 1;
for(int i = 2;i <= n;i++)
ans = (ans * sum[i])%mod;
printf("%lld",ans);
return 0;
}