• 【网络流24题】孤岛营救问题(最短路)


    【网络流24题】孤岛营救问题(最短路)

    题面

    Cogs

    题解

    这。。。不就是状压之后跑一遍SPFA吗。。。。
    不想多说了

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define MAX 30
    #define INF 1000000000
    inline int read()
    {
    	int x=0,t=1;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=-1,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return x*t;
    }
    struct Line
    {
    	int v,next,w;
    }e[MAX*MAX*MAX*MAX];
    int n,m,p,K;
    int h[MAX*MAX],cnt=1,key[MAX*MAX];
    int g[MAX][MAX],tot;
    int door[MAX*MAX][MAX*MAX];
    int d[4][2]={1,0,0,1,-1,0,0,-1};
    int dis[MAX*MAX][1<<12];
    bool vis[MAX*MAX][1<<12];
    inline void Add(int u,int v,int w)
    {
    	e[cnt]=(Line){v,h[u],w};h[u]=cnt++;
    }
    void SPFA()
    {
    	memset(dis,63,sizeof(dis));
    	dis[1][0]=0;
    	queue<int> Q,Q2;Q.push(1);Q2.push(0);
    	while(!Q.empty())
    	{
    		int u=Q.front(),t=Q2.front();
    		Q.pop();Q2.pop();
    		for(int i=h[u];i;i=e[i].next)
    		{
    			int v=e[i].v,gg=t|key[v];
    			if((e[i].w&t)!=e[i].w)continue;
    			if(dis[v][gg]>dis[u][t]+1)
    			{
    				dis[v][gg]=dis[u][t]+1;
    				if(!vis[v][gg])vis[v][gg]=true,Q.push(v),Q2.push(gg);
    			}
    		}
    		vis[u][t]=false;
    	}
    }
    int main()
    {
    	freopen("rescue.in","r",stdin);
    	freopen("rescue.out","w",stdout);
    	n=read();m=read();p=read();
    	K=read();
    	for(int i=1;i<=n;++i)
    		for(int j=1;j<=m;++j)
    			g[i][j]=++tot;
    	for(int i=1;i<=K;++i)
    	{
    		int x1=read(),y1=read(),x2=read(),y2=read();
    		int u=g[x1][y1],v=g[x2][y2];
    		door[u][v]=door[v][u]=read()-1;
    		if(door[u][v]!=-1)door[u][v]=door[v][u]=1<<door[v][u];
    	}
    	for(int i=1;i<=n;++i)
    		for(int j=1;j<=m;++j)
    			for(int k=0;k<4;++k)
    			{
    				int x=i+d[k][0],y=j+d[k][1];
    				if(x&&y&&x<=n&&y<=m)
    					if(door[g[i][j]][g[x][y]]!=-1)
    						Add(g[i][j],g[x][y],door[g[i][j]][g[x][y]]);
    			}
    	K=read();
    	while(K--)
    	{
    		int x=read(),y=read(),u=g[x][y];
    		key[u]|=1<<(read()-1);
    	}
    	SPFA();
    	int ans=INF;
    	for(int i=0;i<(1<<10);++i)ans=min(ans,dis[tot][i]);
    	if(ans>=INF){puts("-1");return 0;}
    	printf("%d
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    出队列操作
    出队列操作
    栈和队列7 数据结构和算法29
    KE上传图片
    asp.net常用快捷键
    基于jquery框架实现以下行的向上、向下和删除
    each的用法积累
    JTemplate使用2
    kindeditor API ,kindeditor使用手册,kindeditor函数,kindeditor使用,超级大收集(转载)
    线上帮助
  • 原文地址:https://www.cnblogs.com/cjyyb/p/8193112.html
Copyright © 2020-2023  润新知