zoukankan      html  css  js  c++  java
  • 电路维修

    【题目描述】:
    电路维修

    【思路】:
    开先看起来挺迷的,觉得没法做,搜索也写不出来。。。

    再仔细分析题目,发现对于任意一根电路,它只有两种状态:

    • 连着右上和坐下
    • 连着左下和右上

    要求最小的操作数。
    我们可以发现,每条电线可以花费1的代价从一种状态改变为另外一种状态,那么我们可以对于已经连着的两点连一条权为0的边,没连着的连一条花费为1的边,求出从左上角到右下角的最短路即可。
    注:卡(SPFA),建议用(SLF) (or) (LLL) (or) 堆优化的(DJ),此处用的(SLF)优化。

    #include<cstdio>
    #include<queue>
    #include<cstring>
    #define inf 0x3f3f3f3f
    using namespace std;
    
    int n,m;
    
    const int MAXN = 251005;
    
    struct edge{
        int u,v,w,nxt;
    }e[MAXN<<2];int head[MAXN];int cnt = 0;int ed;int dis[MAXN];bool vis[MAXN];char c[505];
    
    inline void add(int u,int v,int w){
        e[++cnt].u = u;e[cnt].v = v;e[cnt].w = w;e[cnt].nxt = head[u];head[u] = cnt;
    }
    
    deque<int>q;
    inline void spfa(){
        q.push_back(1);
        memset(vis,0,sizeof vis);
        memset(dis,inf,sizeof dis);
        dis[1] = 0;
        
        while(!q.empty()){
            int u = q.front();q.pop_front();vis[u] = 0;
            for(int i=head[u];i;i=e[i].nxt){
                int v = e[i].v;
                if(dis[v] > dis[u] + e[i].w){
                    dis[v] = dis[u] +e[i].w;
                    if(!vis[v]){
                        vis[v] = 1;
                        if(e[i].w == 0) q.push_front(v);
                        else q.push_back(v);
                    }
                }
            }
        }
        
        printf("%d
    ",dis[ed]);
    }
    
    int main(){
        int T;scanf("%d",&T);
        while(T--){
            scanf("%d%d",&n,&m);
            memset(head,0,sizeof head);cnt = 0;
            for(int i=1;i<=n;++i){
                scanf("%s",c+1);
                for(int j=1;j<=m;++j){
                    if(c[j] == '/'){
                        add(j+1+(i-1)*(m+1) , j+i*(m+1) , 0);
                        add(j+i*(m+1) , j+1+(i-1)*(m+1) , 0);
                        add(j+(i-1)*(m+1) , j+1+i*(m+1) , 1);
                        add(j+1+i*(m+1) , j+(i-1)*(m+1) , 1);
                        
                    }
                    else{
                        add(j+1+(i-1)*(m+1) , j+i*(m+1) , 1);
                        add(j+i*(m+1) , j+1+(i-1)*(m+1) , 1);
                        add(j+(i-1)*(m+1) , j+1+i*(m+1) , 0);
                        add(j+1+i*(m+1) , j+(i-1)*(m+1) , 0);
                    }
                }
            }
            if((n+m)%2) {puts("NO SOLUTION");continue;}
            ed = (n + 1) * (m + 1);
            spfa();
        }
        return 0;
    }
    
  • 相关阅读:
    用iptables 实现本地端口转发
    hive查询
    IOS畅销榜
    java多线程系列7-停止线程
    java多线程系列6-阻塞队列
    java多线程系列5-死锁与线程间通信
    java多线程系列4-线程池
    java多线程系列3-线程同步
    java多线程系列2-线程控制
    java多线程系列1--线程实现与调度
  • 原文地址:https://www.cnblogs.com/lajioj/p/9743700.html
Copyright © 2011-2022 走看看