[网络流24题-6]孤岛营救问题

孤岛营救问题

为什么又是奇奇怪怪的混进来的题啊QAQ

又没想出网络流解法啊QAQ

看见P是10就又状压了吖QwQ

bfs跑一遍就吼了w

为啥子网络流24题总是状压+最短路/bfs啊QAQ

哦对记得门和墙要建双向边[哭晕]

#include
#include
#include
#include
#include
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 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\n",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\n",-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\n",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

 

你可能感兴趣的:(题解,————图论————,网络流,最短路)