POJ-3268-Silver Cow Party

本文介绍了一个关于牛聚会的问题,每头牛需要从各自所在的田地出发,前往聚会地点并返回。通过SPFA算法两次求解各点到聚会地点的最短路径,以确定所有牛往返的最长总时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

描述:

块田中(1≤N≤1000)都有1只牛去参加盛大的母牛聚会,这个聚会被安排在X号田(1≤X ≤N)。一共有M( 1≤M≤100,000)条单行道分别连接着两块田,且通过路i需要花Ti(1≤Ti≤100)的时间。每头母牛必需参加宴会并且在宴会结束时回到自己的田地,但是每头牛都很懒而喜欢选择化是最少的一个方案。来时的路和去时的可能不一样。求每头牛要来回的最短时间。

找出来回路程最长的。输出来回最长的距离。

大意就直接复制别人的了,解法就是2次求各点到x的最短路径。只是存的时候需要存2次,因为路径是单向路径,并非无向图,所以需要特殊处理一下。这个题用SPFA比较简单,2次求后找出最大值就OK。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#define MAX 100001
using namespace std;
int n,m,x,e,pnt[MAX],cost[MAX],nxt[MAX],head[MAX],dist[MAX],vis[MAX];
int ea,pnta[MAX],costa[MAX],nxta[MAX],heada[MAX],dista[MAX];
const int  inf=1<<28;
void addedge(int u,int v,int c)
{
    pnt[e]=v;nxt[e]=head[u];cost[e]=c;head[u]=e++;
}
void addedgea(int u,int v,int c)
{
    pnta[ea]=v;nxta[ea]=heada[u];costa[ea]=c;heada[u]=ea++;
}
void SPFA(int x,int *head,int *pnt,int *cost,int *nxt,int *dist)
{
    for(int i=0;i<=n;i++)
	dist[i]=inf;
    memset(vis,0,sizeof(vis));
    dist[x]=0;
    queue<int> q;
    q.push(x);
    while(!q.empty())
    {
	int u=q.front();
	q.pop();
	vis[u]=0;
	for(int i=head[u];i!=-1;i=nxt[i])
	{
	    int v=pnt[i];
	    if(dist[u]+cost[i]<dist[v])
	    {
		dist[v]=dist[u]+cost[i];
		if(!vis[v])
		{
		    vis[v]=1;
		    q.push(v);
		}
	    }
	}
    }
}
int main()
{
    while(scanf("%d%d%d",&n,&m,&x)!=EOF)
    {
	e=ea=0;
	memset(head,-1,sizeof(head));
	memset(heada,-1,sizeof(heada));
	for(int i=0;i<m;i++)
	{
	    int a,b,c;
	    scanf("%d%d%d",&a,&b,&c);
	    addedge(a,b,c);
	    addedgea(b,a,c);
	}
	    SPFA(x,head,pnt,cost,nxt,dist);
	    SPFA(x,heada,pnta,costa,nxta,dista);
	    int ans=0;
	    for(int i=1;i<=n;i++)
		ans=max(ans,dist[i]+dista[i]);
	    printf("%d\n",ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值