牛客 - 导航系统(最小生成树+Floyd)

题目链接:点击查看

题目大意:有 n 个城市由 n - 1 条边连接成一个连通块,给出一个 n * n 的距离矩阵,代表 n 个城市中每两个城市之间的最短路,问该矩阵是否合法,如果合法从小到大输出 n - 1 条边

题目分析:比赛的时候没反应过来这个题的题意是想干什么,补题的时候发现原来就是一个最小生成树,因为 n 个点由 n - 1 条边组成了联通块,很显然是一棵树,题目又说了需要显示城市之间的最短距离,这就暗示了这棵树就是 n 个城市的最小生成树,现在给出的矩阵是否合法,我们只需要先判断一下是否对称(废话),然后再利用这个矩阵建边然后跑出最小生成树,利用这个最小生成树跑一遍 Floyd ,最后与原距离矩阵比较一下是否相同就可以判断是否合法了

代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<unordered_map>
using namespace std;
     
typedef long long LL;
    
typedef unsigned long long ull;
     
const int inf=0x3f3f3f3f;
     
const int N=510;

struct Edge
{
	int u,v,w;
	Edge(int u,int v,int w):u(u),v(v),w(w){}
	bool operator<(const Edge& a)const
	{
		return w<a.w;
	}
};

vector<Edge>edge;

vector<int>ans;

int maze[N][N],dis[N][N],f[N];

int find(int x)
{
	return x==f[x]?x:f[x]=find(f[x]);
}

bool merge(int x,int y)
{
	int xx=find(x);
	int yy=find(y);
	if(xx!=yy)
	{
		f[xx]=yy;
		return true;
	}
	return false;
}
 
int main()
{
//#ifndef ONLINE_JUDGE
//  freopen("input.txt","r",stdin);
//    freopen("output.txt","w",stdout);
//#endif
//  ios::sync_with_stdio(false);
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    	f[i]=i;
    for(int i=1;i<=n;i++)
    	for(int j=1;j<=n;j++)
    	{
    		scanf("%d",&maze[i][j]); 
    		dis[i][j]=i==j?0:inf;
		}
    for(int i=1;i<=n;i++)
    	for(int j=i+1;j<=n;j++)
    	{
    		edge.push_back(Edge(i,j,maze[i][j]));
    		if(maze[i][j]!=maze[j][i])
    			return 0*printf("No");
		}
	sort(edge.begin(),edge.end());
	for(auto it:edge)
	{
		if(merge(it.u,it.v))
		{
			ans.push_back(it.w);
			dis[it.u][it.v]=dis[it.v][it.u]=it.w;
		}
	}
    for(int k=1;k<=n;k++)
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++)
    			dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
    for(int i=1;i<=n;i++)
    	for(int j=1;j<=n;j++)
    		if(maze[i][j]!=dis[i][j])
    			return 0*printf("No");
    puts("Yes");
    for(auto it:ans)
    	printf("%d\n",it);
    
      
        
        
        
        
        
        
        
    return 0;
}
发布了646 篇原创文章 · 获赞 20 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_45458915/article/details/104337963