黑暗城堡-(最小生成树+最短路)
Posted darlingroot
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了黑暗城堡-(最小生成树+最短路)相关的知识,希望对你有一定的参考价值。
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\n",i,dis[i]);
// puts("\n");
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\n",i,sum[i]);
ll ans = 1;
for(int i = 2;i <= n;i++)
ans = (ans * sum[i])%mod;
printf("%lld",ans);
return 0;
以上是关于黑暗城堡-(最小生成树+最短路)的主要内容,如果未能解决你的问题,请参考以下文章