[蓝桥杯][2013年第四届真题]大臣的旅费

1438: [蓝桥杯][2013年第四届真题]大臣的旅费

菜鸟生成记(3)

这一题真是搞人心态,扣了一周,不是超时,就是爆栈;后来看到大神用邻接表数组和vector写的,想参考一下;看了一两天,愣是没看出个所以然(没学过STL,邻接表数组太绕了,脑子不好使T-T);
心态爆炸!最后去问数据结构老师,老师直接给我说了一通:“我没教过STL和邻接表数组,难道我没有教过邻接表吗?”;唉!裂开了,上课划水,还让老师知道了;没办法,找到以前的课件,开始恶补;弄懂了十之七八;直接照搬;还好AC;前几天"撕心裂肺",不过现在看来都是值得;爽!
说了一堆废话,上AC代码(下面还有超时和爆栈的代码)
#include<bits/stdc++.h>
using namespace std;
#define N 100000//这个范围题上没说,1e+4(只能通过80%),1e+5(可AC)
typedef struct st{
	int v;//结点编号 
	int w;//权值 
	struct st *nx;//结点指针(指向下一个结点) 
}ll,*link;//类型 
struct sx{
	ll *next;//表头后面跟的结点 
}s[N];//邻接表的表头 
int n;
int book[N]={0};
int str=0;//记录两次最远距离 
int max1=-1;//最大权值 
void dfs(int x,int k)
{//x:结点编号; k:权值累加和;  
	if(k>max1)
	{
		max1=k;//记录最大权值 
		str=x;//记录访问最远的结点编号 
	}
	link p;
	p=s[x].next;
	while(p)
	{
		if(book[p->v]==0)
		{
			book[p->v]=1;//访问后标记 
			dfs(p->v,k+p->w);
			book[p->v]=0;//取消标记供寻走到尽头返回后再使用 
		}
		p=p->nx;
	}
	return;
}
/*
5 
1  2  2 
1  3  1 
2  4  5 
2  5  4 
*/
int main()
{
	int w,sum=0;
	cin>>n;
	link p;
	int x,y;
	for(int i=1;i<=n;i++)
	{
		s[i].next=0;
	}
	for(int i=1;i<=n-1;i++)
	{//建立邻接表,这是个无向图,需要两部分
	// 这个建表过程是根据我们数据结构老师的课件改的
	//我学的不精,不知道该怎么详细描述;
	//根据邻接矩阵把邻接表画出来,对于理解这个建表过程有很大的帮助 
		scanf("%d%d%d",&x,&y,&w);
		int th=x;
		p=new ll;
		p->v=y;
		p->w=w;
		p->nx=s[th].next;
		s[th].next=p;
	/*********有向表,下面就不用写了**********/ 
		th=y;
		p=new ll;
		p->v=x;
		p->w=w;
		p->nx=s[th].next;
		s[th].next=p;
	}
	book[1]=1;
	dfs(1,0);//从结点1,权值为0开始,;
	//前面的全局变量str记录从结点能到达最远的结点 
	memset(book,0,sizeof(book));//置0,供下一个dfs使用 
	book[str]=1;
	dfs(str,0);//从结点str,权值为0开始,
	//cout<<"str = "<<str<<endl;
	sum=max1*10+max1*(max1+1)/2;
	cout<<sum<<endl;
	return 0;
}
超时80%代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e+5;
struct st{
	int x;
	int y;
	int w;
}s[N];
int n,str=0,max1=-1;
int book[N]={0};
//int a[N][N]={0};
void dfs(int x,int k,int step)
{
	if(k>max1)
	{
		max1=k;
		str=x;
	}
	if(step==n)
	{
		return;
	}
	for(int i=1;i<=2*(n-1);i++)
	{
		int x1=s[i].x;
		int y1=s[i].y;
		int w1=s[i].w;
		if(book[y1]==0&&x1==x)
		{
			book[y1]=1;
			dfs(y1,k+w1,step+1);
			book[y1]=0;
		}
	}
}
/*
5 
1  2  2 
1  3  1 
2  4  5 
2  5  4 
*/
int main()
{
	cin>>n;
	int sum=0;
	for(int i=1;i<=n-1;i++)
	{
		int x,y,w;
		cin>>x>>y>>w;
		s[i+n-1].y=s[i].x=x;
		s[i+n-1].x=s[i].y=y;
		s[i+n-1].w=s[i].w=w;
	}
	//for(int i=1;i<=2*(n-1);i++)
	//{
		//printf("%d %d %d\n",s[i].x,s[i].y,s[i].w);
	//}
	book[1]=1;
	dfs(1,0,1);
	//cout<<"str = "<<str<<endl;
	//cout<<max1<<endl;
	max1=-1;
	memset(book,0,sizeof(book));
	book[str]=1;
	dfs(str,0,1);
	//cout<<"str = "<<str<<endl;
	//cout<<max1<<endl;
	sum=max1*10+max1*(max1+1)/2;
	cout<<sum<<endl;
	return 0;
}
爆栈(内存超限)
#include<stdio.h>
#include<string.h>
#define N 10001
#define max(x,y) x>y?x:y
struct st{
	int a;
	int b;
	int w;
}s[N];
int a[N][N];
int book[N];
int n;
int x,y,sum=0,max1=0;
fun(int x,int k)
{
	if(k>sum)
	{
		sum=k;
	}
	for(int i=1;i<=n;i++)
	{
		if(a[x][i]!=0&&book[i]==0)
		{
			book[i]=1;
			fun(i,k+a[x][i]);
			book[i]=0;
		}
	}
}
int main()
{
	
	scanf("%d",&n);
	memset(a,0,sizeof(a));
	for(int i=0;i<n-1;i++)
	{
		scanf("%d%d%d",&s[i].a,&s[i].b,&s[i].w);
		x=s[i].a;
		y=s[i].b;
		a[x][y]=s[i].w;
		a[y][x]=s[i].w;
	}
	for(int i=1;i<=n;i++)
	{
		sum=0;
		book[i]=1;
		fun(i,0);
		book[i]=0;
		max1=max(sum,max1);
	}
	sum=0;
	sum=max1*10+max1*(max1+1)/2;
	printf("%d",sum);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值