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

浙公网安备 33010602011771号