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

    P2243 电路维修

    题目背景

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

    题目描述

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

    输入输出格式

    输入格式:

     

    输入文件包含多组测试数据。第一行包含一个整数T 表示测试数据的数目。

    对于每组测试数据,第一行包含正整数 R 和C,表示电路板的行数和列数。

    之后 R 行,每行C 个字符,字符是"/"和""中的一个,表示标准件的方向。

    对于40% 的数据,R,C≤5。

    对于 100% 的数据,R,C≤500,T≤5。

     

    输出格式:

     

    对于每组测试数据,在单独的一行输出一个正整数,表示所需的缩小旋转次数。

    如果无论怎样都不能使得电源和发动机之间连通,输出 NO SOLUTION。

     

    输入输出样例

    输入样例#1:
    1
    3 5
    \/\
    \///
    /\\
    
    输出样例#1:
    1

    说明

    样例的输入对应于题目描述中的情况。

    只需要按照下面的方式旋转标准件,就可以使得电源和发动机之间连通。

    思路:跑最短路。

    错因:数组开小了,边数太多spfa会TLE应该用dijstra

    60分代码:

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define MAXN 350010
    using namespace std;
    char s[1010];
    int t,r,c,tot;
    int vis[MAXN],dis[MAXN];
    int to[MAXN*2],net[MAXN*2],cap[MAXN*2],head[MAXN*2];
    void add(int u,int v,int w){
        to[++tot]=v;net[tot]=head[u];cap[tot]=w;head[u]=tot;
        to[++tot]=u;net[tot]=head[v];cap[tot]=w;head[v]=tot;
    }
    void spfa(int s){
        queue<int>que;
        memset(vis,0,sizeof(vis));
        memset(dis,0x3f,sizeof(dis));
        que.push(s);
        dis[s]=0;vis[s]=1;
        while(!que.empty()){
            int now=que.front();
            que.pop();
            vis[now]=0;
            for(int i=head[now];i;i=net[i])
                if(dis[to[i]]>dis[now]+cap[i]){
                    dis[to[i]]=dis[now]+cap[i];
                    if(!vis[to[i]]){
                        vis[to[i]]=1;
                        que.push(to[i]);
                    }
                }
        }
    }
    int main(){
        scanf("%d",&t);
        while(t--){
            tot=0;
            memset(head,0,sizeof(head));
            scanf("%d%d",&r,&c);
            for(int i=1;i<=r;i++){
                scanf("%s",s);
                for(int j=0;j<c;j++)
                    if(s[j]=='/'){
                        add((i-1)*(c+1)+j+2,i*(c+1)+j+1,0);
                        add((i-1)*(c+1)+j+1,i*(c+1)+j+2,1);
                    }    
                    else{
                        add((i-1)*(c+1)+j+1,i*(c+1)+j+2,0);
                        add((i-1)*(c+1)+j+2,i*(c+1)+j+1,1);
                    }
            }
            spfa(1);
            if(dis[(r+1)*(c+1)]==0x3f3f3f3f)    cout<<"NO SOLUTION"<<endl;
            else     cout<<dis[(r+1)*(c+1)]<<endl;
        }
    }

    AC代码:

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define MAXN 1050010
    using namespace std;
    struct nond{
        int number,dis;
        bool operator < (nond b) const{
            return dis>b.dis;
        }
    };
    char s[1010];
    int t,r,c,tot;
    int dis[MAXN];
    int to[MAXN*2],net[MAXN*2],cap[MAXN*2],head[MAXN*2];
    void add(int u,int v,int w){
        to[++tot]=v;net[tot]=head[u];cap[tot]=w;head[u]=tot;
        to[++tot]=u;net[tot]=head[v];cap[tot]=w;head[v]=tot;
    }
    void dijkstra(int s){
        priority_queue<nond>que;
        memset(dis,0x3f,sizeof(dis));
        que.push((nond){s,0});
        dis[s]=0;
        while(!que.empty()){
            nond now=que.top();
            que.pop();
            if(dis[now.number]!=now.dis)    continue;
            for(int i=head[now.number];i;i=net[i])
                if(dis[to[i]]>dis[now.number]+cap[i]){
                    dis[to[i]]=dis[now.number]+cap[i];
                    que.push((nond){to[i],dis[to[i]]});
                }
        }
    }
    int main(){
        scanf("%d",&t);
        while(t--){
            tot=0;
            memset(head,0,sizeof(head));
            scanf("%d%d",&r,&c);
            for(int i=1;i<=r;i++){
                scanf("%s",s+1);
                for(int j=1;j<=c;j++)
                    if(s[j]=='/'){
                        add((i-1)*(c+1)+j+1,i*(c+1)+j,0);
                        add((i-1)*(c+1)+j,i*(c+1)+j+1,1);
                    }    
                    else{
                        add((i-1)*(c+1)+j,i*(c+1)+j+1,0);
                        add((i-1)*(c+1)+j+1,i*(c+1)+j,1);
                    }
            }
            dijkstra(1);
            if(dis[(r+1)*(c+1)]==0x3f3f3f3f)    cout<<"NO SOLUTION"<<endl;
            else     cout<<dis[(r+1)*(c+1)]<<endl;
        }
    }
    细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。 雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。
  • 相关阅读:
    WPF中C#代码触发鼠标点击事件
    PHP代码实现强制换行
    C#中判断系统的架构(32位,还是64位)
    WPF的System.Windows.Threading.DispatcherTimer的使用(每隔一定的时间重复做某事)
    LINQ to Objects系列(2)两种查询语法介绍
    LINQ to Objects系列(1)相关技术准备
    常用技术社区和网站总结
    .net项目技术选型总结
    java与.net比较学习系列(7) 属性
    java与.net比较学习系列(6) 数组
  • 原文地址:https://www.cnblogs.com/cangT-Tlan/p/7517922.html
Copyright © 2011-2022 走看看