P2243 电路维修

P2243 电路维修

题目背景
Elf 是来自Gliese 星球的少女,由于偶然的原因漂流到了地球上。在她无依无靠的时候,善良的运输队员Mark 和James 收留了她。Elf 很感谢Mark和James,可是一直也没能给他们帮上什么忙。

题目描述
有一天 Mark 和James 的飞行车没有办法启动了,经过检查发现原来是电路板的故障。飞行车的电路板设计很奇葩,如下图所示:


错误日志: 调完有点激动, 没判无解直接交了


Solution

可以证明, 一个电路不会被反转多于 \(1\)
所以有边连边, 权为 \(0\) , 无边连边权为 \(1\) ,代表需要翻转一次
听说卡 \(SPFA\) 于是交了个 \(SPFA(SLF)\) \(A\)

Code

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#define LL long long
#define REP(i, x, y) for(int i = (x);i <= (y);i++)
using namespace std;
int RD(){
    int out = 0,flag = 1;char c = getchar();
    while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
    while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
    return flag * out;
    }
const int maxn = 500 * 500 * 4 + 19 ,INF = 1e9 + 19;
int head[maxn],nume = 1;
struct Node{
    int v,dis,nxt;
    }E[maxn << 3];
void add(int u,int v,int dis){
    E[++nume].nxt = head[u];
    E[nume].v = v;
    E[nume].dis = dis;
    head[u] = nume;
    }
int T, lenx, leny;
void addEDG(int x, int y, int o){//o == 0 : \  //
    int id = (x - 1) * (leny + 1) + y;
    add(id, id + leny + 2, 0 ^ o);
    add(id + leny + 2, id, 0 ^ o);
    add(id + 1, id + leny + 1, 1 ^ o);
    add(id + leny + 1, id + 1, 1 ^ o);
    }
int d[maxn];
bool inq[maxn];
void SPFA(int s){
    deque<int>Q;
    d[s] = 0;
    Q.push_front(s);
    inq[s] = 1;
    while(!Q.empty()){
        int u = Q.front();Q.pop_front();inq[u] = false;
        for(int i = head[u];i;i = E[i].nxt){
            int v = E[i].v, dis = E[i].dis;
            if(d[u] + dis < d[v]){
                d[v] = d[u] + dis;
                if(!inq[v]){
                    if(Q.empty() || d[v] <= d[Q.front()])Q.push_front(v);
                    else Q.push_back(v);
                    inq[v] = 1;
                    }
                }
            }
        }
    }
char s[maxn];
int main(){
    T = RD();
    while(T--){
        lenx = RD(), leny = RD();
        int t = (lenx - 1) * (leny + 1) + leny + 2 + leny;
        nume = 1, memset(head, 0, sizeof(head));
        REP(i, 1, t)d[i] = 1e9;
        REP(i, 1, lenx){
            cin>>s;
            REP(j, 1, leny){
                if(s[j - 1] == '/')addEDG(i, j, 1);
                else addEDG(i, j, 0);
                }
            }
        SPFA(1);
        if(d[t] == 1e9)puts("NO SOLUTION");
        else printf("%d\n", d[t]);
        }
    return 0;
    }

猜你喜欢

转载自www.cnblogs.com/Tony-Double-Sky/p/9762970.html