邻接表笔记

题目:ROADS POJ - 1724

vjudge提交链接

题意:

有n个点(编号为1,2,3…n),有m条单向路,每条路有相应的长度l,以及每条路的过路费t
一个人要从1号点走到n号点,问在不超过花费mo的情况下最短路是多少。

思路:

利用邻接表去存每条边的信息
然后利用dfs暴搜即可。

构建邻接表:

add(ss,dd,ll,tt);
邻接表函数:
void add(int x,int y,int ll,int tt)
{
	nx[head]=first[x];
	first[x]=head;
	l[head]=ll;
	t[head]=tt;
	to[head]=y;
	head++;
}
//l,t,to具有相同的下标,可用结构体来存.
//便于理解就没有用到结构体

初始head=1;
邻接表建立,head在不断增加,相当于重新建立一个边的信息表. 
first[x]中x表示顶点,而fisrt[x]为新的编号(新的信息表对应的标号),
假设head=first[x],那
y=to[head]就表示与x相连的点,
l[head]就表示x到y的长度, 
t[head]就表示x到y的过路费

与顶点x相连的顶点可能有多个,因此这里在解释first,nx,to数组
下述所提的编号是题中所给m行边信息对应的编号
first[x]:
存储的就是以顶点x为始点的最后一条边所对应的编号,
设i=first[x],若i!=-1,则nx[i]存的是以x为始点倒数第二条边的编号,
...
nx数组:
根据上述所说,nx数组存储的是也是边的编号,作用就是寻找以x为始点的边的编号。
注意nx数组的下标不是顶点,而是m行中对应的某边的编号。
to数组:
存储的就是与始点x相连的顶点,所存的是顶点。注意to数组的下标也不是顶点,而是新建立的信息表中的编号。

建立双向邻接表与建立单向邻接表过程一致,始点和末点反转再调用一次即可。

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
int first[101],nx[10001],to[10001],l[10001],t[10001],head;//n+1,m+1,m+1,m+1
int mo,n,m,minl,book[101];
void add(int x,int y,int ll,int tt)
{
	nx[head]=first[x];
	first[x]=head;
	l[head]=ll;
	t[head]=tt;
	to[head]=y;
	head++;
}
void dfs(int x,int suml,int sumt)
{
	if(x==n)
	{
		minl=min(minl,suml);
		return; 
	}
	for(int i=first[x];i!=-1;i=nx[i])
	{
		int y=to[i];
		if(!book[y]&&suml+l[i]<minl&&sumt+t[i]<=mo)
		{
			book[y]=1;
			dfs(y,suml+l[i],sumt+t[i]);
			book[y]=0;
		}
	}
}
int main()
{
	while(~scanf("%d",&mo))
	{
		memset(first,-1,sizeof(first));
		memset(book,0,sizeof(book));
		scanf("%d %d",&n,&m);
		int ss,dd,ll,tt;
		for(int i=1;i<=m;i++)
		{
			scanf("%d %d %d %d",&ss,&dd,&ll,&tt);
			add(ss,dd,ll,tt);
		}
		minl=INF;
		book[1]=1;
		dfs(1,0,0);
		if(minl==INF)
			printf("-1\n");
		else
			printf("%d\n",minl);
	}
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值