• 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;
    }
    


     

  • 相关阅读:
    美国独立电影人制作的纪录片《南京梦魇——南京大屠杀》
    我的黑莓电子书阅读解决方案
    NativeExcel 破解笔记
    右键刷新弹出网页广告的解决办法
    可恶的硬件故障(已解决)
    XP系统无法出现关机界面的解决一例
    任务栏无任务显示的问题
    centos 删除指定文件之外的其他文件
    Canvas中的save方法和restore方法
    博弈论取石子问题
  • 原文地址:https://www.cnblogs.com/LUO257316/p/3220862.html
Copyright © 2020-2023  润新知