做题记录整理图论4 P4011 孤岛营救问题(2022/10/11)
分层图,让我感觉大开眼界,原来分层图是这么用的
题解
#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;
}

浙公网安备 33010602011771号