做题记录整理图论4 P4011 孤岛营救问题(2022/10/11)

P4011 孤岛营救问题

分层图,让我感觉大开眼界,原来分层图是这么用的
题解

#include<bits/stdc++.h>
#define for1(i,a,b) for(int i = a;i<=b;i++)
#define ll long long
#define mp(a,b) make_pair(a,b)
using namespace std;
struct node{
	int to;
	int nex;
	int w;
}a[1000005];
struct node2{
	int x;
	int y;
}s[15][20];
int n,m,cnt,row,l,sn;
int ji,r,num[20][20];
int fg[205][205],jl[19],hd[102405],dis[102405];
int q[1000005],inf=1e9;
bool vis[102405],h[15];
void ru( int x,int y,int w)
{
	a[++cnt].to=y;
	a[cnt].w=w;
	a[cnt].nex=hd[x];
	hd[x]=cnt;
	
}
void cl()
{
	int x,y,t;
	m=row*l;        
	ji=1<<sn;    
	n=m*ji;        
	for1(k,0,ji)       
	{
		for1(i,1,sn)
		if(k&(1<<(i-1))) h[i]=true;
		else h[i]=false;
		for1(i,1,row)     
		{
			for1(j,1,l)
			{
				x=num[i][j];
				y=num[i][j+1];     
				if(y!=0&&fg[x][y]!=-1)  
				{
					if(fg[x][y]==0||h[fg[x][y]])
					{
						ru(k*m+x,k*m+y,1);
						ru(k*m+y,k*m+x,1);
					}
				}
				y=num[i+1][j];          
				if(y!=0&&fg[x][y]!=-1)
				{
					if(fg[x][y]==0||h[fg[x][y]])
					{
						ru(k*m+x,k*m+y,1);
						ru(k*m+y,k*m+x,1);
					}
				}			
			}
		}
		for1(i,1,sn)           
		{
			if(!h[i])          
			{
				t=k+(1<<(i-1));     
				for1(j,1,jl[i])   
				{
					x=num[s[i][j].x][s[i][j].y];
					ru(k*m+x,t*m+x,0);
				}
			}
		}
	} 
}
void spfa()
{
	int k,head,tail;
	for1(i,1,n) dis[i]=inf;
	dis[1]=0;
	vis[1]=true;
	head=tail=1;q[1]=1;
	while(head<=tail)
	{
		int i=q[head];
		for(int k=hd[i];k;k=a[k].nex)
		{
			int v=a[k].to;
			if(dis[v]>dis[i]+a[k].w)
			{
				dis[v]=dis[i]+a[k].w;
				if(!vis[v])
				{
					q[++tail]=v;
					vis[v]=true;
				}
			}
		}
		vis[i]=false;
		head++;
	}
}
int main()
{
		int x,y,p,k=0;
	scanf("%d %d %d %d",&row,&l,&sn,&r);
	for1(i,1,row) 
		for1(j,1,l)
		k++,num[i][j]=k;      
	for1(i,1,r)
	{
		scanf("%d %d",&x,&y);
		int j=num[x][y];
		scanf("%d %d",&x,&y);
		int k=num[x][y];
		scanf("%d",&p);
		if(p==0) 
		    p=-1;          
		fg[j][k]=p;
		fg[k][j]=p;
	}
	scanf("%d",&r);
	for1(i,1,r)
	{
		scanf("%d %d %d",&x,&y,&p);
		jl[p]++;
		s[p][jl[p]].x=x;      
		s[p][jl[p]].y=y;
	}
	cl();
	
	spfa();	
	int ans=inf,T;
	T=num[row][l];
	for1(i,0,ji-1)
	ans=min(ans,dis[i*m+T]);
	if(ans<inf) printf("%d",ans);
	else printf("-1");
	return 0;
}
posted @ 2022-10-11 19:28  yyx525jia  阅读(23)  评论(0)    收藏  举报