[BZOJ3889]USACO2015 Jan-Cow|最短路

挺傻逼的一道题,犯了一些傻逼错误,还写了对拍,拍出了别人的错误。。就是把航线上的每个点对暴力建边,然后跑双关键字最短路即可。。inf要开的够大。。

#include<cstdio>
#include<iostream>
#include<memory.h>
#define ll long long
#define N 10005
#define inf 0x3f3f3f3f3f3f3f3fll
using namespace std;
struct edge{
	int e,next,cnt;
	ll q;
}ed[N*500];
ll dis[N];
int A,B,n,i,j,len,k,c,ne=0,a[N],city[N],que[N],inq[N],b[N],last[N];
void add(int s,int e,ll q,int cnt)
{
	ed[++ne].e=e;ed[ne].q=q;ed[ne].cnt=cnt;
	ed[ne].next=a[s];a[s]=ne;
}
void spfa()
{
	int head,tail,hh,tt,get,j;
	head=tail=hh=tt=1;
	for (i=0;i<=1000;i++) inq[i]=0,dis[i]=inf,city[i]=inf;
	inq[A]=1;que[1]=A;dis[A]=0;city[A]=0;
	while (hh<=tt)
	{
		get=que[head++];hh++;
		if (head>10000) head=1;
		for (j=a[get];j;j=ed[j].next)
			if (dis[get]+ed[j].q<dis[ed[j].e]||(dis[get]+ed[j].q==dis[ed[j].e]&&city[get]+ed[j].cnt<city[ed[j].e]))
			{
				last[ed[j].e]=get;
				dis[ed[j].e]=dis[get]+ed[j].q;city[ed[j].e]=city[get]+ed[j].cnt;
				if (!inq[ed[j].e])
				{
					tail++;tt++;
					if (tail>10000) tail=1;
					que[tail]=ed[j].e;inq[ed[j].e]=1;
				}
			}
		inq[get]=0;
	}
}
int main()
{
//	freopen("3889.in","r",stdin);
//	freopen("my.out","w",stdout);
	scanf("%d%d%d",&A,&B,&n);
	memset(a,0,sizeof(a));
	for (i=1;i<=n;i++)
	{
		scanf("%d%d",&c,&len);
		for (j=1;j<=len;j++) scanf("%d",&b[j]);
		for (j=1;j<=len;j++)
			for (k=j+1;k<=len;k++)
				add(b[j],b[k],(ll)c,k-j);
	}
	spfa();
	if (dis[B]==inf) puts("-1 -1");else if (A==B) puts("0 1");else printf("%I64d %d\n",dis[B],city[B]);
	j=B;
//	while (j!=A) printf("%d ",dis[last[j]]),j=last[j];
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值