洛谷P4011 孤岛营救问题(状压+BFS)
和网络流有半毛钱关系么……
可以发现$n,m,p$都特别小,那么考虑状压,每一个状态表示位置以及钥匙的拥有情况,然后每次因为只能走一步,所以可以用bfs求出最优解
然后是某大佬说的注意点:每个点可以有很多钥匙,而且初始点也有可能有钥匙
1 //minamoto 2 #include<iostream> 3 #include<cstdio> 4 #include<queue> 5 using namespace std; 6 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 7 char buf[1<<21],*p1=buf,*p2=buf; 8 inline int read(){ 9 #define num ch-'0' 10 char ch;bool flag=0;int res; 11 while(!isdigit(ch=getc())) 12 (ch=='-')&&(flag=true); 13 for(res=num;isdigit(ch=getc());res=res*10+num); 14 (flag)&&(res=-res); 15 #undef num 16 return res; 17 } 18 const int N=11; 19 int vis[N][N][(1<<N)],map[N][N][N][N],pas[N][N][N],num[N][N]; 20 struct node{ 21 int x,y,step,now; 22 node(){} 23 node(int x,int y,int step,int now):x(x),y(y),step(step),now(now){} 24 }; 25 queue<node> q; 26 int dx[]={0,0,1,-1},dy[]={1,-1,0,0}; 27 int n,m,p,k; 28 int bfs(){ 29 int now=0; 30 for(int i=1;i<=num[1][1];++i) 31 now|=(1<<(pas[1][1][i]-1)); 32 vis[1][1][now]=1; 33 q.push(node(1,1,0,now)); 34 while(!q.empty()){ 35 node u=q.front();q.pop(); 36 if(u.x==n&&u.y==m) return u.step; 37 for(int i=0;i<4;++i){ 38 int xx=u.x+dx[i],yy=u.y+dy[i],t; 39 if(xx<1||xx>n||yy<1||yy>m) continue; 40 if(map[u.x][u.y][xx][yy]==-1) continue; 41 if((t=map[u.x][u.y][xx][yy])) 42 if(!(u.now&(1<<(t-1)))) continue; 43 int nowx=u.now; 44 for(int j=1;j<=num[xx][yy];++j) 45 nowx|=(1<<(pas[xx][yy][j]-1)); 46 if(vis[xx][yy][nowx]) continue; 47 vis[xx][yy][nowx]=1; 48 q.push(node(xx,yy,u.step+1,nowx)); 49 } 50 } 51 return -1; 52 } 53 int main(){ 54 n=read(),m=read(),p=read(),k=read(); 55 for(int i=1;i<=k;++i){ 56 int x1,x2,y1,y2,g; 57 x1=read(),y1=read(),x2=read(),y2=read(),g=read(); 58 if(g==0) map[x1][y1][x2][y2]=map[x2][y2][x1][y1]=-1; 59 else map[x1][y1][x2][y2]=map[x2][y2][x1][y1]=g; 60 } 61 int s=read(); 62 for(int i=1;i<=s;++i){ 63 int x=read(),y=read(),p=read(); 64 pas[x][y][++num[x][y]]=p; 65 } 66 printf("%d\n",bfs()); 67 return 0; 68 }
深深地明白自己的弱小