现在的位置: 首页 > 综合 > 正文

hdu1125–附上多个最短路方法代码

2017年02月22日 ⁄ 综合 ⁄ 共 4155字 ⁄ 字号 评论关闭

最近学习最短路算法,发现这个题目基本上能用很多最短路方法解,于是贴出所有代码:spfa邻接矩阵、spfa--数组邻接表、dijikstra、floyd、bellman_ford

spfa--邻接矩阵版

// AC 176k 0ms
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;

#define MAX 10//想不通的是本来这里我用10 去调试..可以提交的时候忘了改..也过了..无语

int N;//N个经纪人
int v[MAX][MAX];//邻接表v[i][j]表示i号经纪人人到j号经纪人的时间
int d[MAX];//d[i]表示源点(也就是每次起点)到i的最少时间
bool flag[MAX];//每次spfa 对于每一个点入队一次,标记入队

void Input()
{
	int m,to,time;//每个人的m个朋友,以及用时
	memset(v,0,sizeof(v));
	for(int i=1;i<=N;i++)
	{
		scanf("%d",&m);
		while(m--)
		{
			scanf("%d%d",&to,&time);
			v[i][to]=time;
		}
	}
}

void spfa()
{
	int i,j;
	int ans[MAX];
	for(i=1;i<=N;i++) ans[i]=0;
	for(i=1;i<=N;i++)//1到N都spfa一次
	{
		for(j=1;j<=N;j++) d[j]=1001,flag[j]=false;//这里之所以d[i]初始化为1001,是因为100个人,每个人传达10 应该不会超过1001
		d[i]=0;
		flag[i]=true;
		queue<int> q;
		q.push(i);
		while(!q.empty())
		{
			int u=q.front();q.pop();
			for(j=1;j<=N;j++)
				if(v[u][j]!=0 && d[j]>d[u]+v[u][j])// && !flag[j]这里注意...不管j在不在队列,都要松弛一次
				{
					d[j]=d[u]+v[u][j];//松弛
					if(!flag[j])
					{
						flag[j]=true;q.push(j);
					}
				}
		}
		for(j=1;j<=N;j++)//一次spfa之后 d[]最大的就是本次的i到所有点的最短用时,即最短路
			ans[i]= ans[i]>d[j] ? ans[i]:d[j];
	}
	int ANS1=1001,ANS2;
	for(i=1;i<=N;i++)//取每个起点的最短路中 最小的值
		if(ANS1>ans[i])
			ANS1=ans[i],ANS2=i;
    if(ANS1!=1001)
	    printf("%d %d\n",ANS2,ANS1);
}

int main()
{
	while(scanf("%d",&N),N)
	{
		Input();
		spfa();
	}
	return 0;
}

spfa数组邻接表

// AC 180k 16ms
#include<cstdio>
#include<queue>
using namespace std;

#define MAX 1001

struct node
{
	int to,time;
	int next;
}edge[MAX*2];
int head[MAX];
int tol;

void add(int st,int end,int time)
{
	edge[tol].to=end;
	edge[tol].time=time;
	edge[tol].next=head[st];
	head[st]=tol++;
}

int N;

void init()
{
	int i;
	for(i=1;i<=N;i++) head[i]=-1;
	tol=0;
	
	for(i=1;i<=N;i++)
	{
		int m,to,time;
		scanf("%d",&m);
		while(m--)
		{
			scanf("%d%d",&to,&time);
			add(i,to,time);
		}
	}
}

int d[MAX];
bool flag[MAX];
int spfa(int s)
{
	int i;
	for(i=1;i<=N;i++) flag[i]=false, d[i]=10*MAX;
	d[s]=0;

	queue<int>q;q.push(s);

	while(!q.empty())
	{
		int u=q.front();q.pop(); flag[u]=false;

		for(int j=head[u];j!=-1;j=edge[j].next)
		{
			int v=edge[j].to,w=edge[j].time;
			if(d[v]>d[u]+w)
			{
				d[v]=d[u]+w;
				if(!flag[v]) flag[v]=true,q.push(v);
			}
		}
	}
	int ans=0;
	for(i=1;i<=N;i++)
		if(d[i]>ans) 
			ans=d[i];
	return ans;
}

int  main()
{
	while(scanf("%d",&N),N)
	{
		init();
		int ans=10*MAX,ans_start;
		for(int i=1;i<=N;i++)
		{
			int x=spfa(i);
			if(x<ans)
				ans=x,ans_start=i;
		}
		printf("%d %d\n",ans_start,ans);
	}
	return 0;
}

floyd--不用说肯定是邻接矩阵:

// 168k 0ms
#include<stdio.h>

#define MAX 6
#define INF 1<<29
int N;
int map[MAX][MAX];

void init()
{
	int i,to,m,time;
	for(i=1;i<=N;i++)
		for(int j=1;j<=N;j++)
			map[i][j]=INF;
	for(i=1;i<=N;i++)
	{
		scanf("%d",&m);
		while(m--)
		{
			scanf("%d%d",&to,&time);
			map[i][to]=time;
		}
	}
}

void floyd()
{
	int i,j,k;
	for(k=1;k<=N;k++)
		for(i=1;i<=N;i++)
			for(j=1;j<=N;j++)
				if(i!=j) map[i][j]=map[i][j]>map[i][k]+map[k][j] ? map[i][k]+map[k][j]:map[i][j];

    int ans1,ans2=INF;
	for(i=1;i<=N;i++)
	{
		int max=0;
		for(j=1;j<=N;j++)
			if(i!=j && map[i][j]>max) max=map[i][j];
			if(max<ans2) ans2=max,ans1=i;
	}
	printf("%d %d\n",ans1,ans2);
}

int main()
{
	while(scanf("%d",&N),N)
	{
		init();
		floyd();
	}
	return 0;
}

dijikstra-邻接矩阵

#include<stdio.h>

#define MAX 100

int N;
int map[MAX][MAX];

void init()
{
	int i,j;
	for(i=1;i<=N;i++)
		for(j=1;j<=N;j++)
			map[i][j]=0;
	int m,to,time;
	for(i=1;i<=N;i++)
	{
		scanf("%d",&m);
		while(m--)
		{
			scanf("%d%d",&to,&time);
			map[i][to]=time;
		}
	}
}

int d[MAX];
bool flag[MAX];
int Dijkstra(int s)
{
	int i,j;
	for(i=1;i<=N;i++) flag[i]=false,d[i]=1001;
	d[s]=0;

	for(i=1;i<=N;i++)
	{
		int u=0,max=1001;
		for(j=1;j<=N;j++)
		{
			if(!flag[j] && max>d[j])
				u=j,max=d[j];
		}
		if(u==0) break;
		flag[u]=true;
		for(j =1; j<=N;j++)
			if(map[u][j]!=0 && d[j]>d[u]+map[u][j])
				d[j]=d[u]+map[u][j];
	}
	int ans=0;
	for(i=1;i<=N;i++)
		ans=ans>d[i] ? ans:d[i];
	return ans;
}

int main()
{
	while(scanf("%d",&N),N)
	{
		init();
		int ans1=1001,ans2;
		for(int i=1;i<=N;i++)
		{
		   int x=Dijkstra(i);
		   if(ans1>x)
			   ans1=x,ans2=i;
		}
		printf("%d %d\n",ans2,ans1);
	}
	return 0;
}

bellman_ford--结构体数组

//AC 168k 0ms
#include<stdio.h>

#define MAX 101

struct node
{
	int st,end,time;
}edge[MAX];
int tol;

int N;

void init()
{
	int i;
	tol=0;
	int m,to,time;
	for(i=1;i<=N;i++)
	{
		scanf("%d",&m);
		while(m--)
		{
			scanf("%d%d",&to,&time);
			edge[tol].st=i,edge[tol].end=to,edge[tol++].time=time;
		}
	}
}
int d[MAX];
int Bellman_ford(int s)
{
	int i;
	for(i=1;i<=N;i++) d[i]=1001;
	d[s]=0;
	for(i=1;i<N;i++)
	{
		for(int j=0;j<tol;j++)
		{
			int u=edge[j].st,v=edge[j].end,w=edge[j].time;
			d[v]=d[u]+w<d[v] ? d[u]+w:d[v];//松弛
		}
	}
	int ans=0;
	for(i=1;i<=N;i++)
		ans=ans>d[i] ? ans:d[i];
	return ans;
}

int main()
{
	while(scanf("%d",&N),N)
	{
		init();
		int ans1=1001,ans2;
		for(int i=1;i<=N;i++)
		{
			int x=Bellman_ford(i);
		   if(ans1 > x)
			   ans1=x,ans2=i;
		}
		printf("%d %d\n",ans2,ans1);
	}
	return 0;
}

【上篇】
【下篇】

抱歉!评论已关闭.