Stockbroker Grapevine

题目链接:http://vjudge.net/contest/view.action?cid=47127#problem/B


题目大意:

输入一个有向带权图,求一个起点,使其能遍历所有顶点并且时间最短。即求出其最小生成图的半径。

 

思路:

先要用floyd算法求出这个有向图的最小生成图。然后算出各个顶点的ecc(eccentricity),即可知图的radius。


算法步骤:

步骤1:floyd算法对图进行整理。

		//floyd
		for(int k = 1; k <= n; k++)
		    for(int i = 1; i <= n; i++)
		        for(int j = 1; j <= n; j++)
		            if(dis[i][j] > dis[i][k] + dis[k][j])
		                dis[i][j] = dis[i][k] + dis[k][j];
复杂度为O(n^3)

步骤2:计算各点的ecc。

		//computing ecc
		for(int i = 1; i <= n ; i++)
		{
			for(int j = 1; j <= n; j++)
			{
				//cout<<dis[i][j]<<" ";
				if(dis[i][j] > ecc[i])
				    ecc[i] = dis[i][j];
			}
			//cout<<endl;
		}
复杂度O(n^2)


步骤3,找出中心点,并判断图是否连通,若连通,则输出该点序号及生成图的半径。

		int cen = 1;//center point		
		//choose the one with minimum ecc
		for(int i = 1 ; i <= n ; i ++)
		{
			//cout<<"ecc["<<i<<"] = "<<ecc[i]<<endl;
			if(ecc[i] < ecc[cen])
		        cen = i;
		}
		
		//output
		if( ecc[cen] == INF)//disconnected
		    cout << "disjoint" << endl;
		else cout << cen << " " << ecc[cen]<<endl;


完整代码如下:

#include <iostream>
#include "memory.h"
#define INF 0x3f3f3f3f
using namespace std;

int dis[105][105];//distance matrix
int ecc[105];//max eccentricity for each people 

int main()
{
    int n;
    while(cin>>n, n != 0)//n people
    {
		memset(dis,0x3f,sizeof(dis));//initialization
		memset(ecc,0,sizeof(ecc));
		int m;//connecting number for each people
		for(int i = 1; i <= n; i ++)//n people
		{
			cin>>m;
			int k,value;
			dis[i][i] = 0;
			if (m != 0)
			    for (int j = 1; j <= m; j++)
			    {
				    cin>>k>>value;
				    dis[i][k] = value;
			    }
		}
		
		//floyd
		for(int k = 1; k <= n; k++)
		    for(int i = 1; i <= n; i++)
		        for(int j = 1; j <= n; j++)
		            if(dis[i][j] > dis[i][k] + dis[k][j])
		                dis[i][j] = dis[i][k] + dis[k][j];
		
		
		//computing ecc
		for(int i = 1; i <= n ; i++)
		{
			for(int j = 1; j <= n; j++)
			{
				//cout<<dis[i][j]<<" ";
				if(dis[i][j] > ecc[i])
				    ecc[i] = dis[i][j];
			}
			//cout<<endl;
		}
		
		int cen = 1;//center point		
		//choose the one with minimum ecc
		for(int i = 1 ; i <= n ; i ++)
		{
			//cout<<"ecc["<<i<<"] = "<<ecc[i]<<endl;
			if(ecc[i] < ecc[cen])
		        cen = i;
		}
		
		//output
		if( ecc[cen] == INF)//disconnected
		    cout << "disjoint" << endl;
		else cout << cen << " " << ecc[cen]<<endl;
		
	}
    return 0;
}

评测系统上运行结果:Accepted,运行时间0ms,占用内存260KB.



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值