zoukankan      html  css  js  c++  java
  • 黑暗城堡 最短路径生成树

    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);//输出
    }
    
  • 相关阅读:
    Unity在协程内部停止协程自身后代码执行问题
    unity如何停止不用字符串方式开启协程的方法
    解决导入protobuf源代码Unity报错的问题
    FastCGI模式编译安装LAMP+Xcache
    Apache配置防盗链
    Apache配置日志切割
    Apache配置参数的优化
    Apache三种工作模式详解
    隐藏Nginx、Apache、PHP的版本号
    配置Apache控制浏览器端的缓存的有效期
  • 原文地址:https://www.cnblogs.com/Lance1ot/p/9228414.html
Copyright © 2011-2022 走看看