电路维修

电路维修

Solution.1

双端队列搜索,权值为\(0\)的边放在队头,权值为\(1\)放在队尾

Code.1

#include<deque>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
deque<pair<int,int> > dq;
pair<int,int> t;
int T,n,m,dis[505][505], vis[505][505];
char a[505][505];
void work(int x,int y,int d,int bj){
    if(dis[x][y] > d + bj){
        dis[x][y] = d + bj;
        if(bj) dq.push_back(pair <int, int> (x, y));
        else dq.push_front(pair <int, int> (x, y));
    }
}
void BFS()
{
    int x, y, now;
    dq.clear();
    dq.push_front(pair <int, int> (1, 1));
    memset(dis, 0x7f, sizeof dis);
    memset(vis, 0, sizeof(vis));
    dis[1][1] = 0;//多次数据记得初始化
    while(!dq.empty()){
        t = dq.front();
        dq.pop_front();
        x = t.first, y = t.second;
        now = dis[x][y];
        if(vis[x][y]){
        	continue;
        }
        vis[x][y] = 1;
        if(x > 1 && y > 1) work(x - 1, y - 1, now, a[x-1][y-1] != '\\');
        if(x > 1 && y <= m) work(x - 1, y + 1, now, a[x-1][y] != '/'); 
        if(x <= n && y > 1) work(x + 1, y - 1, now, a[x][y-1] != '/'); 
        if(x <= n && y <= m) work(x + 1, y + 1, now, a[x][y] != '\\');
    }
    printf("%d\n",dis[n+1][m+1]);
}
int main(){
    scanf("%d", &T);
    for(int i = 1; i <= T; ++i){
        scanf("%d%d", &n, &m);
        for(int j = 1; j <= n; ++j) scanf("%s", a[j] + 1);
        if((n + m) % 2){
            printf("NO SOLUTION\n");
            continue;
        }
        BFS();
    }
    return 0;
}

Solution.2

最短路,复习\(dji\),因为可能双向边,以及其他的某种情况,所以要记录\(vis[i]\),\(pair\)是先比较\(frst\),然后比较\(second\)

Code.2

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <cstring>
#include <queue>
#include <cmath>
using std::priority_queue;
using std::pair;
using std::make_pair;
using std::greater;
using std::vector;

typedef pair<int,int> Pair;

const int N = 505000;
const int M = 2e6;

struct Edge{
    int to, val, next;
}e[M];

int cnt, head[N], dis[N], vis[N];
char s[505];

inline void addedge(int x, int y, int z){
    e[++cnt].to = y;
    e[cnt].next = head[x];
    e[cnt].val = z;
    head[x] = cnt;
    return;
}

inline void dji(){
    memset(vis, 0, sizeof(vis));
    memset(dis, 0x3f, sizeof(dis));
    priority_queue <Pair, vector<Pair>, greater<Pair> > q;
    dis[1] = 0;
    q.push(make_pair(0, 1));
    while(!q.empty()){
        Pair u = q.top();
        q.pop();
        if(vis[u.second]) continue;
        vis[u.second] = 1; 
        for(int i = head[u.second]; i; i = e[i].next){
            if(dis[u.second] + e[i].val < dis[e[i].to]){
                dis[e[i].to] = dis[u.second] + e[i].val;//即便是已经被水流流过的点,也可能更新 
                if(!vis[e[i].to]){ 
                    q.push(make_pair(dis[e[i].to], e[i].to));
                }
            }
        }
    }
}

int main(){
    int t;
    scanf("%d", &t);
    while(t--){
        memset(head, 0, sizeof(head));
        memset(e, 0, sizeof(e));
        cnt = 0;
        int n, m;
        scanf("%d %d", &n, &m);
        for(int i = 1, la, lb, lc, ld; i <= n; ++i){
            scanf("%s", s + 1);
            for(int j = 1; j <= m; ++j){
                if(s[j] == '/'){
                    la = (m + 1) * (i - 1) + j;
                    lb = (m + 1) * (i - 1) + j + 1;
                    lc = (m + 1) * i + j;
                    ld = (m + 1) * i + j + 1;
                    addedge(lb, lc, 0);
                    addedge(lc, lb, 0);
                    addedge(la, ld, 1);
                    addedge(ld, la, 1);
                }else{				
                    la = (m + 1) * (i - 1) + j;
                    lb = (m + 1) * (i - 1) + j + 1;
                    lc = (m + 1) * i + j;
                    ld = (m + 1) * i + j + 1;
                    
                    addedge(lb, lc, 1);
                    addedge(lc, lb, 1);
                    addedge(la, ld, 0);
                    addedge(ld, la, 0);
                }
            }
        }
        
        dji();
        if(dis[(m + 1) * (n + 1)] ==  1061109567)
            puts("NO SOLUTION");
        else printf("%d\n", dis[(m + 1) * (n + 1)]);		
    }
    
    return 0;
}
posted @ 2018-09-07 16:55  LMSH7  阅读(133)  评论(0编辑  收藏  举报