• 51nod_1445 变色DNA 最短路模板 奇妙思维


    这是一道最短路模板题,但是在理解题意和提出模型的阶段比较考验思维,很容易想到并且深深进入暴力拆解题目的无底洞当中。

    题意是说:给出一个邻接矩阵,在每个点时,走且仅走向,合法路径中编号最小的点。问题是是否能够从0点走向n-1点。如果可以走到,求出,最少应当删除几个合法边(如果(1,2)(2,1)(2,3)同时合法,前两个边就会不停的循环,这时候必须删掉(2,1)才能够让(2,3)这条边被走到,从而到达新的节点)。

    题解:重新定义变得权重:按照题意变得权重应当每次是1,但是显然在这道题的设定下,这个权重并没有意义。因此应当重新定义每条边的权重:使得邻接矩阵path[i][j]代表的含义是:如果要合法的走过这条边,应当删除前面的几条边?

    普通的dijkstra:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 long long cases,n,m;
     5 const long long MAXN=50+23;
     6 const long long INF=1e12+233;
     7 long long path[MAXN][MAXN];
     8 long long dp[MAXN];
     9 
    10 void init()
    11 {
    12     cin>>n;    
    13     for(int i=0;i<n;++i)
    14     {
    15         dp[i]=INF;long long point=0;
    16         for(int j=0;j<n;++j)
    17             {
    18                 path[i][j]=INF;
    19                 char c;
    20                 cin>>c;
    21                 
    22                 if(c!='N')
    23                 {
    24                     path[i][j]=point;
    25                     point++;
    26                 }
    27             }
    28     }
    29 }
    30 bool v[MAXN];
    31 void dijkstra()
    32 {
    33     memset(v,0,sizeof(v));
    34     dp[0]=0;int x=0;
    35     for(int i=0;i<n;++i)
    36     {
    37         long long mini=INF;
    38         for(int j=0;j<n;++j)
    39         {
    40             if(!v[j]&&dp[j]<mini)
    41             {
    42                 mini=dp[j];
    43                 x=j;
    44             }
    45         }v[x]=1;
    46         for(int j=0;j<n;++j)
    47         {
    48             dp[j]=min(dp[j],dp[x]+path[x][j]);
    49         }
    50     }
    51     
    52     if(dp[n-1]==INF)cout<<"-1"<<endl;
    53     else cout<<dp[n-1]<<endl;
    54 }
    55 
    56 int main()
    57 {
    58     cin.sync_with_stdio(false);
    59     cin>>cases;
    60     for(int itee=0;itee<cases;++itee)
    61     {
    62         init();
    63         dijkstra();
    64     }
    65     return 0;
    66 }

     两行代码的解决方案:

    1 #include<bits/stdc++.h>
    2 using namespace std;long long cases,n,m;const long long MAXN=50+23;const long long INF=1e12+233;long long path[MAXN][MAXN];long long dp[MAXN];void init(){    cin>>n;        for(int i=0;i<n;++i)    {        dp[i]=INF;long long point=0;        for(int j=0;j<n;++j)            {                path[i][j]=INF;                char c;                cin>>c;                                if(c!='N')                {                    path[i][j]=point;                    point++;                }            }    }}bool v[MAXN];void dijkstra(){    memset(v,0,sizeof(v));    dp[0]=0;int x=0;    for(int i=0;i<n;++i)    {        long long mini=INF;    for(int j=0;j<n;++j)    {        if(!v[j]&&dp[j]<mini)    {    mini=dp[j];    x=j;    }    }v[x]=1;    for(int j=0;j<n;++j)    {            dp[j]=min(dp[j],dp[x]+path[x][j]);}}    if(dp[n-1]==INF)cout<<"-1"<<endl;    else cout<<dp[n-1]<<endl;}int main(){    cin.sync_with_stdio(false);    cin>>cases;    for(int itee=0;itee<cases;++itee)    {        init();        dijkstra();    }    return 0;}
  • 相关阅读:
    mybatis foreach 循环 list(map)
    zust_第二周——瞎扯系列
    Codeforces Round #271 (Div. 2)-B. Worms
    Codeforces Round #271 (Div. 2)-A. Keyboard
    2014年牡丹江现场赛打铁记
    Codeforces Round #274 (Div. 2)-C. Exams
    Codeforces Round #274 (Div. 2)-B. Towers
    Codeforces Round #274 (Div. 2)-A. Expression
    二叉树
    Codeforces Round #273 (Div. 2)-C. Table Decorations
  • 原文地址:https://www.cnblogs.com/rikka/p/7326038.html
Copyright © 2020-2023  润新知