zoukankan      html  css  js  c++  java
  • 51nod-1445-变色DNA(最短路)

    题意:题目是说从0到n-1,我还是习惯从1到n,所以以下我都这么写,大概题意就是(i, j)==‘Y’表示可以从i颜色变成j颜色,然后问我们最少删除几个会影响结果的‘Y’,能到n这个颜色;

    没有意义的‘Y’:因为题目说了,能变色就一定得变色,而且,每次变色都得变成当前能变的颜色最小的那个,所有有可能执行了某些变色操作会导致变不成n,比如n==4,(1,2)==‘Y’;(3,4)==‘Y’;

    那么会先变成2,然后就没得变了;

    解题思路:

    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<queue>
    #include<cstring>
    #define maxn 10005
    #define inf 0x3f3f3f3f
    using namespace std;
    struct node
    {
        int num;
        int dist;
        node(int _num=0,int _dist=0):num(_num),dist(_dist){}
        friend bool operator<(node a,node b)
        {
            return a.dist>b.dist;
        }
    };
    struct Edge
    {
        int next;
        int to;
        int w;
    }edge[maxn];
    int head[maxn];
    int dist[maxn];
    int cnt;
    int visit[maxn];
    void add(int u,int v,int w)
    {
        edge[cnt].next=head[u];
        edge[cnt].w=w;
        edge[cnt].to=v;
        head[u]=cnt++;
    }
    void dij(int x)
    {
        priority_queue<node>que;
        memset(dist,0x3f3f3f3f,sizeof(dist));
        memset(visit,0,sizeof(visit));
        dist[x]=0;
        que.push(node(x,0));
        while(!que.empty())
        {
            node u=que.top();
            que.pop();
            int now=u.num;
            for(int i=head[now];i!=-1;i=edge[i].next)
            {
                Edge e=edge[i];
                if(dist[e.to]>dist[now]+e.w)
                {
                    dist[e.to]=dist[now]+e.w;
                    que.push(node(e.to,dist[e.to]));
                }
            }
        }
    }
    int main()
    {
        char s[60][60];
        int t;
        int n;
        cin>>t;
        while(t--)
        {
            cin>>n;
            memset(head,-1,sizeof(head));cnt=0;
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                cin>>s[i][j];
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    int cnt=0;
                    if(s[i][j]=='Y')
                    {
                        for(int k=1;k<=j-1;k++)
                        {
                            if(s[i][k]=='Y')
                                cnt++;
                        }
                        add(i,j,cnt);
                    }
    
                }
            }
            dij(1);
            if(dist[n]==inf)
            cout<<"-1
    ";
            else
            cout<<dist[n]<<endl;
        }
        return 0;
    }
    

      

    根据先变小的这个操作,所以,我们可以这么建图,(i,j)==‘Y’时,可以建一条从i到j的边,权值为第i行开始从[1,j-1]中‘Y'的数量,因为如果我们要用这条边的话,因为先变小,所以我们得把这一行中比当前小的都删去,删掉一个权值加1;

    代码:

  • 相关阅读:
    HDFS文件操作(基本文件命令)
    <a> 标签
    css text-overflow
    zepto.js 打包自定义模块
    CSS3 box-sizing
    CSS3 Filter
    JQ 导出 Excel
    outline css2
    iphone 操作手势种类
    动手写一个简单的Web框架(模板渲染)
  • 原文地址:https://www.cnblogs.com/huangdao/p/9074158.html
Copyright © 2011-2022 走看看