POJ-1125& NYOJ-426- 多源最短路-spfa

给一个有向图

以i为出发起点,可以计算得到 i到所有点的最短路,取一个最大值 MAXi 

问 以谁为起点,得到的MAXi最小,输出起点编号和MAXi


思路:

就是对每个人求一次最短路, 做n次spfa,


POJ的数据太水了,随便过。。。NYOJ的数据 n=1000 


n次dji+STL优先队列+vector建邻接表会超时  ,邻接表得自己实现才勉强过一秒


最快的是用spfa+自己实现邻接表  


针对本题还有一个非常重要的地方,做spfa前先dfs求一遍连通性,不连通直接continue,不加这部会超时。。。



 
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue> 
#include <set>
#include <vector>
using namespace std; 
int n,m; 

struct node
{  
	int x,v;
	node(){}
	node(int a,int b)
	{ 
		x=a;
		v=b;
	}  
};
struct EDGE
{
    int   u;//起点
    int   v;//终点
    int  len;//边的长度
    int next;
}edge[1005*105+1];//一定要边的范围
int head [1005];//头节点
int k=1;

void init()//初始化信息,-1;
{
    for(int i=1;i<=n;i++)
    head[i]=-1;
    k=1;
}
//插入边
void insert(int u,int v,int len)
{
  edge[k].v=v; edge[k].len=len; edge[k].next=head[u];head[u]=k;k++;//正边
 // edge[k].v=u; edge[k].len=len; edge[k].next=head[v];head[v]=k;k++;//反边
}

int dis[1005];
int vis[1005];
queue<node> q;

const int inf=2147483647;
int st,ed;

int vis333[1005];
int flag;
int dfs(int x)
{
	int i;
	vis333[x]=1;
	for(  i=head[x];i!=-1;i=edge[i].next) 
	{
		int t=edge[i].v;
		if (!vis333[t])
		{ 
			dfs(t);
		}
	}   
	return 0; 
}
int main()
{ 
	void spfa( );
	
	int i,j;
	int x,y;
	while(cin>>n&&n)
	{   
		int num;
		init();
		for (i=1;i<=n;i++)
		{
		 
			scanf("%d",&num);
			for (j=1;j<=num;j++)
			{
				scanf("%d%d",&x,&y);
				//mp[i].push_back(node(x,y));
				insert(i,x,y);
			}
		}
	 
			node minn,maxx;
		minn.v=inf; 
		for (i=1;i<=n;i++)	//n次
		{
			flag=0; 
			for (j=1;j<=n;j++)
				vis333[j]=0;

			dfs(i);
		 	for (j=1;j<=n;j++)
				if (!vis333[j]) 
				{
					flag=1;
					break;
				}
 
			if (flag)
			continue;
			
			st=i; 
			spfa(); 
	
			maxx.v=0;
			for (j=1;j<=n;j++)
			{
				if (dis[j]>maxx.v)
				{
					maxx.v=dis[j];
					maxx.x=i;//  x记录的是 当前方案总耗时 对应的 出发点i
				}
			}
			//maxx得到为 i 开始传播,到全部人 的总耗时
			
			if (maxx.v<minn.v)
				minn=maxx;		//minn记录的是 所有完成传播任务的 耗时的最小值
			
	 	}
		
		if (minn.v==inf)      //图是非联通的
			printf("disjoint\n"); 
		else
			printf("%d %d\n",minn.x,minn.v);
		
	
		
		
	}
	return 0;
	
}

void spfa()
{
	while(!q.empty()) q.pop();
	int i;
	for (i=1;i<=n;i++)
	{
		dis[i]=inf;
		vis[i]=0;
	}
	dis[st]=0;
	//vis[st]=1;
	q.push(node(st,0));
	while(!q.empty())
	{
		node tmp=q.front();
		q.pop();
		int tt=tmp.x;
		vis[tt]=0;
		//for (i=0;i<mp[tt].size();i++)
		for(int i=head[tt];i!=-1;i=edge[i].next)
		{ 
		//	int x=mp[tt][i].x;
		//	int v=mp[tt][i].v;
		int x=edge[i].v;
		int v=edge[i].len;
			if (dis[tt]+v<dis[x])
			{
				dis[x]=dis[tt]+v;
				if (!vis[x])
				{
					q.push(node(x,dis[x]));
					vis[x]=1;
				}
			}
		} 
	}
	
}        


n次dji+STL优先队列+vector建邻接表会超时  ,邻接表得自己实现才勉强过一秒

你可能感兴趣的:(POJ-1125& NYOJ-426- 多源最短路-spfa)