bzoj4395 [Usaco2015 dec]Switching on the Lights

24 篇文章 0 订阅

分析:。。一开始想歪了,以为直接连边做最短路就好,然后发现好像不行,因为如果相邻的也可以,然后又把相邻的连边,结果又发现如果不点亮不能去房间,这样判断的条件就炸了,所以。。直接暴力bfs我在想啥。。

#include<iostream>  
#include<cstdio>  
#include<cstring>  
#include<cmath>  
#include<cstdlib>  
#include<algorithm>  
#include<queue>  
#define F(i,j,n) for(int i=j;i<=n;i++)  
#define D(i,j,n) for(int i=j;i>=n;i--)  
#define ll long long  
#define pa pair<int,int>  
#define maxn 105  
#define maxm 20005  
#define inf 1000000000  
using namespace std;  
queue<pa> q;  
int n,m,cnt=0,a,b,c,d,ans=1,last=1;  
int head[maxn][maxn];  
bool vst[maxn][maxn],on[maxn][maxn];  
const int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};  
struct edge_type  
{  
    int x,y,next;  
}e[maxm];  
inline int read()  
{  
    int x=0,f=1;char ch=getchar();  
    while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}  
    while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}  
    return x*f;  
}  
inline void add_edge(int a,int b,int c,int d)  
{  
    e[++cnt]=(edge_type){c,d,head[a][b]};  
    head[a][b]=cnt;  
}  
int main()  
{  
    n=read();m=read();  
    F(i,1,m)  
    {  
        a=read();b=read();c=read();d=read();  
        add_edge(a,b,c,d);  
    }  
    on[1][1]=true;  
    while (1)  
    {  
        q.push(make_pair(1,1));  
        memset(vst,false,sizeof(vst));  
        vst[1][1]=true;  
        while (!q.empty())  
        {  
            int x=q.front().first,y=q.front().second;  
            q.pop();  
            for(int i=head[x][y];i;i=e[i].next)  
            {  
                int tx=e[i].x,ty=e[i].y;  
                if (!on[tx][ty]){on[tx][ty]=true;ans++;}  
            }  
            F(i,0,3)  
            {  
                int tx=x+dx[i],ty=y+dy[i];  
                if (tx<=0||tx>n||ty<=0||ty>n) continue;  
                if (on[tx][ty]&&!vst[tx][ty])  
                {  
                    vst[tx][ty]=true;  
                    q.push(make_pair(tx,ty));  
                }  
            }  
        }  
        if (last==ans) break;  
        last=ans;  
    }  
    printf("%d\n",ans);  
}  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值