hdu 2962 Trucking

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=2962

方法一:

使用spfa最短路算法,二分查找最大高度。

运行结果:

2962 140MS 612K 1790 B C++
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
#define INF (1<<30)
#define maxn 1005
struct node
{
	int v,lenth,hight;
	node *next;
}*head[maxn],edge[maxn*maxn];
bool vis[maxn];
int h[maxn],d[maxn];
int r,c;
//spfa求高度大于hight的以start为起点的单源最短路径
void spfa(int start,int hight)
{
	for(int i = 1; i <= c; i++)
		d[i] = INF,vis[i] = false;
	d[start] = 0;
	vis[start] = true;
	queue<int>Q;
	Q.push(start);
	while( !Q.empty() )
	{
		int now = Q.front();
		Q.pop();
		vis[now] = false;
		for(node *p = head[now] ; p ; p = p->next)
		{
			if(p->hight >= hight && d[p->v] >= d[now] + p->lenth)
			{
				d[p->v] = d[now] + p->lenth;
				if(!vis[p->v])
				{
					vis[p->v] = true;
					Q.push(p->v);
				}
			}
		}
	}
}
int main()
{
	int i,num = 1,start,end,hight,lenth,l,r,m;
	while(~scanf("%d%d",&c,&r) && (r||c))
	{
		for(i = 1; i <= c; i++)
			head[i] = NULL;
		node *p = edge;
		while( r-- )
		{
			scanf("%d%d%d%d",&start,&end,&hight,&lenth);
			if(hight == -1)
				hight = INF;

			p->v = end;p->lenth = lenth;p->hight = hight;
			p->next = head[start];
			head[start] = p++;
			
			p->v = start;p->lenth = lenth;p->hight = hight;
			p->next = head[end];
			head[end] = p++;
		}
		scanf("%d%d%d",&start,&end,&hight);
		l = 0; r = hight;
		int ans = INF;
		//二分高度,
		while(l <= r)
		{
			m = (l+r)>>1;
			spfa(start,m);
			if(d[end] == INF)//高度太大
				r = m -1;
			else
			{
				hight = m;
				l = m + 1;
				ans = d[end];
			}
		}
		if(num != 1)
			printf("\n");
		if(ans == INF)
			printf("Case %d:\ncannot reach destination\n",num++);
		else
			printf("Case %d:\nmaximum height = %d\nlength of shortest route = %d\n",num++,hight,ans);
	}
	return 0;
}


方法二:

采用并查集使用kruskal最小生成树算法求最大生成树的方式找出最大高度,然后使用spfa求单源最短路径

运行结果:

Accepted 2962 390MS 776K 1944 B C++
#include<iostream>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
const int INF = 1 << 30;
const int maxn = 1005;
struct Savle
{
	int x,y,h;
	bool operator<(const struct Savle &a)const
	{
		return a.h < h;
	}
}save[maxn*maxn];
struct node
{
	int v,h,l;
	
	node *next;
}*head[maxn],edge[maxn*maxn];
int r,c,set[maxn],dis[maxn];
bool vis[maxn];
int find(int x)
{
	if(x != set[x])
		set[x] = find(set[x]);
	return set[x];
}
void spfa(int start,int hight)
{
	for(int i = 1; i <= r; i++)
		dis[i] = INF;
	memset(vis,false,sizeof(vis));
	vis[start] = true;
	dis[start] = 0;
	queue<int>que;
	que.push(start);
	while(!que.empty())
	{
		int now = que.front();
		que.pop();
		vis[now] = false;
		for(node *p = head[now]; p ; p = p->next)
		{
			if(p->h >= hight && dis[p->v] > dis[now] + p->l)
			{
				dis[p->v] = dis[now] + p->l;
				if( !vis[p->v])
				{
					vis[p->v] = true;
					que.push(p->v);
				}
			}
		}
	}
}
int main()
{
	int i,s,e,l,h,num = 1,k;
	node *p;
	while(cin >> r >> c && (r||c))
	{
		for(i = 1; i <= r; i++)
			head[i] = NULL,set[i] = i;
		p = edge;
		k = 0;
		while( c-- )
		{
			cin >> s >> e >> h >> l;
			if(h == -1)h = INF;
			p->v = e;p->h = h; p->l = l;
			p->next = head[s];
			head[s] = p++;
			
			p->v = s;p->h = h;p->l = l;
			p->next = head[e];
			head[e] = p++;
			save[k].x = s,save[k].y = e;save[k++].h = h;
		}
		sort(save,save+k);
		cin >> s >> e >> h;
		int h1 = -1;
		for(i = 0; i < k; i++)
		{
			set[find(save[i].x)] = find(save[i].y);
			if(find(s) == find(e))
			{
				h1 = save[i].h;
				break;
			}
		}
		h = h > h1 ? h1 : h;
		spfa(s,h);
		if(num != 1)
			cout << endl;
		if(dis[e] == INF || h == -1)
			printf("Case %d:\ncannot reach destination\n",num++);
		else
			printf("Case %d:\nmaximum height = %d\nlength of shortest route = %d\n",num++,h,dis[e]);
	}
	return 0;
}


 

原文地址:https://www.cnblogs.com/LUO257316/p/3220862.html