• 黑暗城堡 最短路径生成树


    dark♂城堡(233

    题目描述

    一个图,有n个节点,m条带权值无向边,构造一颗生成树,使得树上的点到根(1)的距离为该点到1的最短距离。输出符合条件的生成树的个数
    答案模取(2^{31}-1)

    输入输出格式略

    数据范围 (n<=1000)


    这道题如果不考虑时间优化的话,跑(O(N^2))的dij是完全可以的;

    如何统计个数? 我们相当于把点i 连在所有比他到根的最短距离短的点上,并且判断是否合法。利用乘法原理计数就可以了。

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    using namespace std;
    int map[1010][1010];
    int point[1010],dis[1010];
    bool vis[1010];
    const long long mode=(1LL<<31)-1;
    bool compare(const int &a,const int &b)
    {
    	return dis[a]<dis[b];
    }
    int main()
    {
    	int n,m;
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++)
    			map[i][j]=0x7ffffff;
    	int a,b,c;
    	for(int i=1;i<=m;i++)
    	{
    		scanf("%d%d%d",&b,&a,&c);
    		map[a][b]=map[b][a]=min(map[a][b],c);
    	}
    	for(int i=1;i<=n;i++)	point[i]=i,dis[i]=0x7ffffff;
    	dis[1]=0;
    	for(int i=1;i<=n;i++)
    	{
    		int cur=-1;
    		for(int j=1;j<=n;j++)
    			if((cur==-1||dis[cur]>dis[j])&&!vis[j])
    				cur=j;
    		vis[cur]=true;
    		for(int j=1;j<=n;j++)
    			dis[j]=min(dis[j],dis[cur]+map[j][cur]);
    	}//n^2 的 dij
    	sort(point+1,point+1+n,compare);//point里存点的标号,然后按照dis排序
    	long long ans=1;
    	for(int i=2;i<=n;i++)
    	{
    		long long tot=0;
    		for(int j=1;j<i;j++)
    			if(dis[point[i]]-map[point[i]][point[j]]==dis[point[j]])//符合条件的点
    				tot+=1;
    		ans=(ans*tot)%mode;//乘法原理计数
    	}
    	printf("%lld",ans);//输出
    }
    
  • 相关阅读:
    centos7与centos6区别
    tomcat在win10系统中安装失败的问题,修改tomcat内存
    centos7关闭防火墙
    Centos7安装FastDFS教程
    Maven详解(四)------ 常用的Maven命令
    Linxu程序构建-Makefile
    版本控制工具-git
    Linux程序调试-常用调试技巧
    Linux工具-编写手册页&发行软件&RPM软件包
    Linux终端-对终端进行读写
  • 原文地址:https://www.cnblogs.com/Lance1ot/p/9228414.html
Copyright © 2020-2023  润新知