【刷题】BZOJ 2346 [Baltic 2011]Lamp

Description

2255是一个傻X,他连自己家灯不亮了都不知道。
某天TZ大神路过他家,发现了这一情况,
于是TZ开始行侠仗义了。
TZ发现是电路板的问题,
他打开了电路板,发现线路根本没有连上!!
于是他强大的脑力可以使某个格子上的线路从\变为/,
或者从/变为。
2255不会电路(因为他什么都不会),但是他想知道TZ最少要用多少次脑力才能使他家的灯变亮。
如果无法变亮,输出“NO SOLUTION”。

n,m<=500

a.jpg

Input

Output

Sample Input

3 5
\/\
\///
/\\

Sample Output

1

Solution

可以先考虑费用流,然后发现其实就是最短路
要改变的话长度为 \(1\) ,不改变长度为 \(0\) ,跑最短路即可

#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=251001+10,inf=0x3f3f3f3f;
int n,m,e,beg[MAXN],s,t,d[MAXN],p[MAXN],nex[MAXN<<3],to[MAXN<<3],w[MAXN<<3];
char str[510];
std::deque<int> q;
template<typename T> inline void read(T &x)
{
    T data=0,w=1;
    char ch=0;
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')w=-1,ch=getchar();
    while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
    x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{
    if(x<0)putchar('-'),x=-x;
    if(x>9)write(x/10);
    putchar(x%10+'0');
    if(ch!='\0')putchar(ch);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline int id(int x,int y)
{
    return (x-1)*(m+1)+y;
}
inline void insert(int x,int y,int z)
{
    to[++e]=y;
    nex[e]=beg[x];
    beg[x]=e;
    w[e]=z;
}
inline int bfs()
{
    for(register int i=1;i<=t;++i)d[i]=inf;
    d[s]=0;
    p[s]=1;
    q.push_back(s);
    while(!q.empty())
    {
        int x=q.front();
        q.pop_front();
        p[x]=0;
        for(register int i=beg[x];i;i=nex[i])
            if(d[to[i]]>d[x]+w[i])
            {
                d[to[i]]=d[x]+w[i];
                if(!p[to[i]])
                {
                    p[to[i]]=1;
                    if(q.empty()||d[to[i]]<d[q.front()])q.push_front(to[i]);
                    else q.push_back(to[i]);
                }
            }
    }
    if(d[t]==inf)return -1;
    else return d[t];
}
int main()
{
    read(n);read(m);
    for(register int i=1;i<=n;++i)
    {
        scanf("%s",str+1);
        for(register int j=1;j<=m;++j)
            if(str[j]=='/')
            {
                insert(id(i+1,j),id(i,j+1),0);
                insert(id(i,j+1),id(i+1,j),0);
                insert(id(i,j),id(i+1,j+1),1);
                insert(id(i+1,j+1),id(i,j),1);
            }
            else
            {
                insert(id(i,j),id(i+1,j+1),0);
                insert(id(i+1,j+1),id(i,j),0);
                insert(id(i+1,j),id(i,j+1),1);
                insert(id(i,j+1),id(i+1,j),1);
            }
    }
    s=id(1,1);t=id(n+1,m+1);
    int ans=bfs();
    if(ans==-1)puts("NO SOLUTION");
    else write(ans,'\n');
    return 0;
}

转载于:https://www.cnblogs.com/hongyj/p/9417593.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值