第三部分 数据结构 -- 第四章 图论算法-1376:信使(msner)

1376:信使(msner)

时间限制: 1000 ms 内存限制: 65536 KB
提交数: 4971 通过数: 2323
【题目描述】
战争时期,前线有n个哨所,每个哨所可能会与其他若干个哨所之间有通信联系。信使负责在哨所之间传递信息,当然,这是要花费一定时间的(以天为单位)。指挥部设在第一个哨所。当指挥部下达一个命令后,指挥部就派出若干个信使向与指挥部相连的哨所送信。当一个哨所接到信后,这个哨所内的信使们也以同样的方式向其他哨所送信。直至所有n个哨所全部接到命令后,送信才算成功。因为准备充足,每个哨所内都安排了足够的信使(如果一个哨所与其他k个哨所有通信联系的话,这个哨所内至少会配备k个信使)。

现在总指挥请你编一个程序,计算出完成整个送信过程最短需要多少时间。

【输入】
第1行有两个整数n和m,中间用1个空格隔开,分别表示有n个哨所和m条通信线路,且1≤n≤100。

第2至m+1行:每行三个整数i、j、k,中间用1个空格隔开,表示第i个和第j个哨所之间存在通信线路,且这条线路要花费k天。

【输出】
一个整数,表示完成整个送信过程的最短时间。如果不是所有的哨所都能收到信,就输出-1。

【输入样例】
4 4
1 2 4
2 3 7
2 4 1
3 4 6
【输出样例】
11


1 floyed算法

1)算法思路:在图中求最短路还是要分开说的,分别是单源最短路和多源最短路,而floyed算法是求多源最短路的,什么是多源最短路呢?简单来说就是用完算法之后能直接写出任意两点间的最短路径长度。floyed算法在本质上是动态规划思想,不断更新最短路径的值,主要思想就是不断判断两个点是否可以通过一个点中继以刷新当前两个点最短路径的估计值,直到每两个点都判断完成。如下图例:
  
  在这里插入图片描述
2、dijkstra算法:思想及其功效:dijkstra算法属於单源最短路算法,简单说就是用过之后,只能直接写出一点到其他任意一点的最短路径长度。这个算法类似于prim算法,找出刷新点所能到达的点,然后再继续刷新。

void dijkstra()
{
    
    vis[1]==0;dis[1]=0;
    for(int i=1;i<=n-1;i++)
    {
        minn=inf;
        for(int j=1;j<=n;j++)
        {
            if(vis[j]==0&&dis[j]<minn)
            {
                k=j;
                minn=dis[j];
            }
        }
        vis[k]=1;
        for(int j=1;j<=n;j++)
        {
            if(dis[j]>dis[k]+map[k][j]&&map[k][j]<inf)
            dis[j]=dis[k]+map[k][j];
        }
    }
}

3 SPFA

图的权值有正的,当然也有负的,对于负边 SPFA能处理负权边。思路和dijkstra有点像。

void SPFA()
{
    for(int i=1;i<=n;i++)
    dis[i]=inf;
    queue<int>q;
    q.push(1);vis[1]=1;dis[1]=0;
    while(q.size())
    {
        x=q.front();q.pop();vis[x]=0;
        for(int i=head[x];i;i=a[i].next)
        {
            int s=a[i].to;
            if(dis[s]>dis[x]+a[i].cost)
            {
                dis[s]=dis[x]+a[i].cost;
                if(vis[s]==0)
                {
                    vis[s]=1;
                    q.push(s);
                }
            }
        }
    }
}

1 floyed算法

#include<cstdio>
#include<iostream>
using namespace std;
int a[1000][1000],n,m,d,b,c;
int maxn = -1;
int main(){
	cin >> n >> m;
	for(int i = 1; i <= n; i++)
	 for(int j = 1; j <= n; j++)
	 a[i][j] = 999999;
	 for(int i = 1; i <= m; i++)
	 {
	 	cin >> d >> b >> c;
	 	a[d][b] = c;
	 	a[b][d] = c;
	 }
	 for(int k = 1; k <= n; k++)
	   for(int i = 1; i <= n; i++)
	     for(int j = 1; j <= n; j++)
	      {
	 	      if(a[i][j] > a[i][k] + a[k][j] )
	 	   {
	 		a[i][j] = a[i][k] +a[k][j];
		   }
	 	
	    }
	 for(int i = 1; i <= n; i++)
	 {
	 	if(maxn <a[1][i])
	 	maxn = a[1][i];
	 }
	
	cout << maxn;
	return 0;
} 

dijkstra算法:

#include<cstdio>
#include<iostream>
#define INF 0X3F3F3F3F
using namespace std;
int n,m,map[1000][1000],dis[1000],vis[1000];
int a,b,maxn = -1,minn,k;
inline void dijkstra(){
	vis[1] = 0;
	dis[1] =0;
	for(int i = 1; i <= n; i++)
	{
		minn = INF;
		for(int j = 1; j <=n; j++)
		{
			if(!vis[j] && dis[j] < minn)
			{
				k = j;
				minn = dis[j];
			}
		}
		vis[k] =1;
		for(int j =1; j <= n;j++)
		{
			if(dis[j] > dis[k] + map[k][j] && map[k][j]  < INF)
			dis[j] = dis[k] + map[k][j];
		}
	}
}
int main(){
	cin >> n >> m;
	for(int i = 1; i <= n; i++)
	{
		for(int j = 1; j <= n; j++)
		map[i][j] = INF;
		dis[i] = INF;
	}
	for(int i = 1; i <= m; i++)
	{
		cin >> a >> b;
		cin >> map[a][b];
		map[b][a] = map[a][b];
	}
	dijkstra();
	for(int i = 1; i <= n; i++)
	 {
	 	if(dis[i] > maxn)
	 	maxn = dis[i];
	 }
	 cout << maxn;
	return 0;
}

SPFA算法

#include<cstdio>
#include<iostream>
#include<queue>
#define INF 0x3f3f3f3f
#define N 1000
using namespace std;
struct map{
	int from;
	int to;
	int cost;
	int next;
}a[N];

int head[N],dis[N],vis[N],n,m,maxn = -1,x,cnt,a1,b1,c1;
void add(int from, int to, int cost){
	a[++cnt].to = to;
	a[cnt].cost = cost;
	a[cnt].next = head[from];
	head[from] = cnt;
}
void SPFA(){
	for(int i = 1; i <= n; i++)
	 dis[i] = INF;
	 queue<int> q;
	 q.push(1);
	 vis[1] = 1;
	 dis[1] = 0;
	 while(q.size()){
	 	x = q.front();
	 	q.pop();
	 	vis[x] = 0;
	 	for(int i = head[x];i;i = a[i].next){
	 		int s = a[i].to;
	 		if(dis[s] > dis[x] + a[i].cost)
	 		{
	 			dis[s] = dis[x] + a[i].cost;
	 			if(vis[s] == 0)
	 			{
	 				vis[s] = 1;
	 				q.push(s);
				 }
			 }
		 }
	 }
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i = 1; i <= m; i++)
	{
		scanf("%d%d%d",&a1,&b1,&c1);
		add(a1,b1,c1);
		add(b1,a1,c1);
	}
	SPFA();
	for(int i = 2; i <= n; i++)
	if(dis[i] > maxn && dis[i] != INF)
	maxn = dis[i];
	printf("%d",maxn);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章