其他分享
首页 > 其他分享> > Floyd——人人都是中间商(50%)

Floyd——人人都是中间商(50%)

作者:互联网

目录

Floyd——人人都是中间商

引入

粗糙的原理分析

注意点

初始化

赋值

适用

  1. 小空间稠密阵
  2. 能接受$ O(n^3)$的题目。

应用

模板题

AcWing 854. Floyd求最短路

#include<bits/stdc++.h>
using namespace std;
const int N= 2e2+10,INF =0x3f3f3f3f;	
int n,m,q;
int dist[N][N];

void floyd()
{
	for(int k=1;k<=n;k++)
	    for(int i=1;i<=n;i++)
	        for(int j=1;j<=n;j++)
	            dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);
}
int main()
{
    memset(dist,0x3f,sizeof(dist));
 
	cin>>n>>m>>q;
	for(int i=1;i<=n;i++)dist[i][i]=0;//起初各自点并没有中介的点,只能自己到达自己 
	for(int i=0;i<m;i++)
	{
		int x,y,z;
		cin>>x>>y>>z;
	    dist[x][y]=min(dist[x][y],z);//有可能出现重边 
	}
	
	floyd();
	
	for(int i=0;i<q;i++)
	{
		int x,y;
		cin>>x>>y;
		if(dist[x][y]!=INF)
		   cout<<dist[x][y]<<endl;
		else cout<<"impossible"<<endl;
	}
	return 0;
}

直径的拼凑问题

#include<bits/stdc++.h>
using namespace std;
const int N = 260,INF = 99999999; 

int n;

struct dot{
	double x,y;
};

char g[N][N];//记录的仅仅是第i个点是否和第j点联通的情况 
double dist[N][N];

void floyd()
{
	for(int k=1;k<=n;k++)
	    for(int i=1;i<=n;i++)
	        for(int j=1;j<=n;j++)
	        	 dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);          
}

double get_dist(dot a,dot b)
{
	return sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) );
}

int main()
{
	cin>>n;	

	for(int i=1;i<=n;i++) dist[i][i]=0;//错误点:不要让后面的操作覆盖掉它 
	dot dots[n+1];
	for(int i=1;i<=n;i++)
	   cin>>dots[i].x>>dots[i].y;
    //读入联通的情况 
	for(int i=1;i<=n;i++)
	    for(int j=1;j<=n;j++)
	    {
	    	cin>>g[i][j];
	    	if(g[i][j]=='1')
	    		dist[i][j]=get_dist(dots[i],dots[j]);
	    	else if(i!=j) 
	    	    dist[i][j]=INF;
		}

    floyd(); 
    //(间接联通)可以借用dist数组来判断联通关系比较模糊的两点之间的情况
	//不用再去写并查集
	//要找直径,就是要确立当前点中到所有连接的点中的最远距离 
	double ans1=0;//答案有可能在自己圈里,新加入的牧场由于长度太小,可能没有对直径产生影响 
	double max_dot_dis[N+1];
	memset(max_dot_dis,0,sizeof(max_dot_dis));

	for(int i=1;i<=n;i++)
	{
	    for(int j=1;j<=n;j++)
	    {
	        if(dist[i][j]!=INF)
	        {
	        	 max_dot_dis[i]=max( max_dot_dis[i], dist[i][j] );  //	cout<<max_dot_dis[i]<<" "; 
				 ans1=max( ans1, max_dot_dis[i] );   
			}
	          
		}
    }
    
	double ans2=INF;//比小要设大,比大要设小 
	for(int i=1;i<=n;i++)
	    for(int j=1;j<=n;j++)
	    	if(dist[i][j]==INF)//如果两者距离比较大(没有联通而已,但还是有距离),则认为两者分属不同的牧场 
			    ans2=min( max_dot_dis[i] + max_dot_dis[j] + get_dist(dots[i],dots[j]) ,ans2);//错误点2:取小 
    cout<<fixed<<setprecision(6)<<max(ans1,ans2);//这里是被迫取其大,两小中取较大者 
	return 0;
}

无向图的最小环问题

标签:dist,int,double,floyd,50%,Floyd,INF,中间商
来源: https://www.cnblogs.com/BeautifulWater/p/15024712.html