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
", d[t]);
		}
	return 0;
	}
原文地址:https://www.cnblogs.com/Tony-Double-Sky/p/9762970.html