孤岛营救问题
为什么又是奇奇怪怪的混进来的题啊QAQ
又没想出网络流解法啊QAQ
看见P是10就又状压了吖QwQ
bfs跑一遍就吼了w
为啥子网络流24题总是状压+最短路/bfs啊QAQ
哦对记得门和墙要建双向边[哭晕]
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
struct node
{
int x,key;
node(){}
node(int _x,int _key){x=_x,key=_key;}
};
int dis[101][1124],n,m,key[111],in[111],p;bool vis[111][1124];
queue<node> que;
int id(int x,int y)// 0~n*m-1
{
return (x-1)*m+y-1;
}
struct edge{int to,lt,lim;}e[1111];int cnt;
void addedge(int x1,int y1,int x2,int y2,int lim)
{
e[++cnt].to=id(x2,y2);e[cnt].lt=in[id(x1,y1)];
e[cnt].lim=lim;in[id(x1,y1)]=cnt;
}
int ans=2002122500;
void dij()
{
//int x,y,tmp;
int tmp;
memset(dis,48,sizeof(dis));
memset(vis,0,sizeof(vis));
dis[0][key[0]]=0;que.push(node(0,key[0]));
while(!que.empty())
{
node cur=que.front();que.pop();
if(vis[cur.x][cur.key]) continue;
vis[cur.x][cur.key]=1;
//printf("QAQ");
tmp=dis[cur.x][cur.key];
if(cur.x==n*m-1) ans=min(ans,tmp);
//int x=cur.x/m+1,y=cur.x%m+1;
for(int i=in[cur.x];i;i=e[i].lt)
{
if((e[i].lim&cur.key)!=e[i].lim) continue;
if(!vis[e[i].to][cur.key|key[e[i].to]])
{
//printf("*%d %d %d %d %d -> %d %d %d %d
",e[i].lim,x,y,cur.key,tmp,e[i].to/m+1,e[i].to%m+1,cur.key|key[e[i].to],tmp+1);;
dis[e[i].to][cur.key|key[e[i].to]]=tmp+1;
que.push(node(e[i].to,cur.key|key[e[i].to]));
}
}
}
}
bool door[11][11][11][11];
int main()
{
int k,i,x1,y1,x2,y2,kk,g,x,y;
//printf("%d
",-1&3);
scanf("%d%d%d",&n,&m,&p);
scanf("%d",&k);
for(i=1;i<=k;i++)
{
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&g);
door[x1][y1][x2][y2]=1;door[x2][y2][x1][y1]=1;
//printf("%d %d %d %d %d
",x1,y2,x2,y2,g);
if(!g) addedge(x1,y1,x2,y2,-1),addedge(x2,y2,x1,y1,-1);
else addedge(x1,y1,x2,y2,1<<(g-1)),addedge(x2,y2,x1,y1,1<<(g-1));
}
for(x=1;x<=n;x++)
{
for(y=1;y<=m;y++)
{
if(x>1&&!door[x][y][x-1][y]) addedge(x,y,x-1,y,0);
if(y>1&&!door[x][y][x][y-1]) addedge(x,y,x,y-1,0);
if(x<n&&!door[x][y][x+1][y]) addedge(x,y,x+1,y,0);
if(y<m&&!door[x][y][x][y+1]) addedge(x,y,x,y+1,0);
}
}
scanf("%d",&g);
for(i=1;i<=g;i++)
{
scanf("%d%d%d",&x,&y,&kk);
key[id(x,y)]|=(1<<kk-1);
}
dij();
if(ans==2002122500)printf("-1
");
else printf("%d
",ans);
return 0;
}