300英雄的危机(heroes)

时间:2019-10-18
本文章向大家介绍300英雄的危机(heroes),主要包括300英雄的危机(heroes)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题面

正解与图书馆馆长的考验一致,都是分层图SPFA;

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int row,line,keyn,haha,r;
struct typekey{
	int x,y;
}key[15][20]={0};
struct node{
	int to;
	int nxt;
	int w;
}a[1000000]={0};
int num[1000][1000],fg[1000][1000],kn[15];
int layer,n,m,tot;
int head[1000000];
void add(int x,int y,int w)
{
	tot++;
	a[tot].to=y;
	a[tot].w=w;
	a[tot].nxt=head[x];
	head[x]=tot;
}
int dis[1000000],vis[1000000],q[1000000],inf=99999999;
void spfa()
{
	int i,j,k,hea,tail;
	for(i=1;i<=n;i++) dis[i]=inf;
	dis[1]=0;
	vis[1]=1;
	hea=tail=1;
	q[1]=1;
	while(hea<=tail)
	{
		i=q[hea];
		for(k=head[i];k;k=a[k].nxt)
		{
			j=a[k].to;
			if(dis[j]>dis[i]+a[k].w)
			{
				dis[j]=dis[i]+a[k].w;
				if(!vis[j])
				{
					q[++tail]=j;
					vis[j]=1;
				}
			}		
		}
		vis[i]=0;
		hea++;
	}
}
void build()
{
	int i,j,k,x,y,t;
	bool havekey[15]={0};
	m=row*line;
	layer=1<<keyn;
	n=m*layer;
	for(k=0;k<layer;k++)
	{	
		for(i=1;i<=keyn;i++)
		{
			if(k&(1<<(i-1))) havekey[i]=1;
			else havekey[i]=0;
		}
		for(i=1;i<=row;i++)
		{
			for(j=1;j<=line;j++)
			{	
				x=num[i][j];
				y=num[i][j+1];
				if(y!=0&&fg[x][y]!=-1)
				{
					if(fg[x][y]==0||havekey[fg[x][y]])
					{
						add(k*m+x,k*m+y,1);
						add(k*m+y,k*m+x,1);
						//cout<<k*m+x<<" "<<k*m+y<<" "<<k*m+y<<" "<<k*m+x<<endl;
					}
				}
				y=num[i+1][j];
				if(y!=0&&fg[x][y]!=-1)
				{
					if(fg[x][y]==0||havekey[fg[x][y]])
					{
						add(k*m+x,k*m+y,1);
						add(k*m+y,k*m+x,1);
						//cout<<k*m+x<<" "<<k*m+y<<" "<<k*m+y<<" "<<k*m+x<<endl;
					}
				}
			}
		}
		for(i=1;i<=keyn;i++)
		{
			if(!havekey[i])
			{
				t=k+(1<<(i-1));
				for(j=1;j<=kn[i];j++)
				{
					x=num[key[i][j].x][key[i][j].y];
					add(k*m+x,t*m+x,0);
					//cout<<k*m+x<<" "<<t*m+y<<endl;
				}
			}
		}
	}
}
void read()
{
	int i,j,k,x,y,p;
	cin>>row>>line>>keyn>>haha;	
	k=0;
	for(int i=1;i<=row;i++)
	{
		for(int j=1;j<=line;j++)
		{
			num[i][j]=++k;
		}
	}
	cin>>r;
	for(int i=1;i<=r;i++)
	{
		scanf("%d%d",&x,&y);j=num[x][y];
		scanf("%d%d",&x,&y);k=num[x][y];
		scanf("%d",&p);
		if(p==0) p=-1;
		fg[j][k]=fg[k][j]=p;
	}
	scanf("%d",&r);
	for(int i=1;i<=r;i++)
	{
		scanf("%d%d%d",&x,&y,&p);
		kn[p]++;
		key[p][kn[p]].x=x;
		key[p][kn[p]].y=y;
	}
}
int main()
{
	memset(fg,0,sizeof(fg));
	read();	
	build();
	spfa();
	int ans=inf;
	for(int i=0;i<layer;i++)
	{
		ans=min(ans,dis[i*m+num[row][line]]);
	}
	if(ans!=inf)
	{
		if(ans<=haha) cout<<ans<<endl;
		else cout<<(ans-haha)*2+haha;
	}
	else cout<<char(92)<<" Oh,no! Tita will die /";
}

原文地址:https://www.cnblogs.com/kamimxr/p/11700417.html