Cow Marathon

这是一篇关于使用树形动态规划解决寻找地图上两个农场之间最远距离问题的文章。博主通过解析POJ1985题目,介绍了如何处理类似树的直径模板题,帮助奶牛在马拉松中尽可能多地运动。

最近老师安排了任务,我要负责树形dp,于是我——懒博主终于要填坑了。

选了一道类似于树的直径模板题de题:POJ1985

博主好心翻译了:(zzy:其实就是Google翻译)

题面:

在听说美国肥胖流行之后,农夫约翰希望自己的奶牛多锻炼身体,所以他决心为自己的奶牛创造一个牛马拉松。 马拉松路线将包括一对农场和一条由一系列道路组成的路径。 由于FJ希望母牛尽可能多地运动,他希望在他的地图上找到彼此距离最远的两个农场(距离以两个农场之间的道路总长度来衡量)。 帮助他确定这个最远的一对农场之间的距离。

输入输出格式:

第1行:两个空格分隔的整数:N和M.
*第2行M + 1:每行包含四个空格分隔的实体,F1,

F2,L和D描述道路。 F1和F2是数字

两个农场由路相连,L是它的长度,D是a

字符,即“N”,“E”,“S”或“W”

从F1到F2的路的方向。

#include"cstdio"
#include"queue"
#include"cstring"
using namespace std;
struct edge  
{  
    int v,next,w;  
};  
queue<int> end;
edge a[2000001];  
int num=0,s=0,p[1000001];  
int dis[1000001];
bool used[1000001];
int read()  
{  
    char c=getchar();  
    while(c<'0'||c>'9')c=getchar();  
    int x=0;  
    while(c>='0'&&c<='9')  
    {  
        x=x*10+c-'0';  
        c=getchar();  
    }  
    return x;  
}  
void add1(int u,int v,int w)  
{  
    a[++num].v=v;  
    a[num].w=w;  
    a[num].next=p[u];  
    p[u]=num;  
}  
void bfs(int i)
{
	end.push(i);
	dis[i]=0;
	used[i]=1;
	while(!end.empty())
	{
		int fro=end.front();
		for(int j=p[fro];j;j=a[j].next)
		if(dis[a[j].v]>dis[fro]+a[j].w)
		{
			dis[a[j].v]=dis[fro]+a[j].w;
			if(!used[a[j].v])
			{
				used[a[j].v]=1;
				end.push(a[j].v);
			}
		}
		end.pop();
		used[fro]=0;
	}
}
int main()
{
	int n,m,u,v,w,max1=-0x7ffffff,max2; char c; 
    memset(p,0,sizeof(p));  
   	n=read();m=read();   
	for(int i=1;i<=n;i++)
	dis[i]=0x7ffffff;
    for(int i=1;i<=n-1;i++)  
    {  
        u=read(),v=read(),w=read();  
		scanf("%c",&c);  
        add1(u,v,w);  
        add1(v,u,w);
    }
	memset(used,0,sizeof(used));  
    bfs(1);
    for(int i=1;i<=n;i++)
	{
		if(dis[i]>max1)max1=dis[i],max2=i;
		dis[i]=0x7ffffff;
	}
	memset(used,0,sizeof(used));
    bfs(max2);
    max1=-0x7ffffff;
    for(int i=1;i<=n;i++)
	{
		if(dis[i]>max1)max1=dis[i];
		dis[i]=0x7ffffff;
	}
	printf("%d",max1);
	return 0;
}


至于为什么填坑。额之前的那个代码似乎数据大一点就过不了了,因为可以优化,因为懒,所以就只好重打一个bfs大法。

之前的坑也填了哦!!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值