• hdu--1224--spfa||dp


    好久不写spfa了 但在纸上写写 还是可以敲出来 它的思想还是还是很简单 这里就不介绍了 掌握spfa真的很好 除非题目的数据故意卡spfa...那就只能用dij去做了或者floyd

    这题 相比一般我们去求 最短路 有稍许不同 但是你只要明白了spfa的思想 就是进行下转换就可以了

    又是打印路径 好多题遇到了啊.. 我还是喜欢用stack去打印 虽然这样会显得多一步for的入栈 但这样只有O(n) 如果tle 肯定也与此无关吧-

    这里 我的建图 就是一般的使用struct的邻接表 本来想写下 前向星的 发现对于head数组 有点生疏了 就不写了 还是我现在写的这个容易理解 你可以将它看成自己模拟了个vector来实现 很像的

          touch   me

      1 #include <iostream>
      2 #include <cstring>
      3 #include <queue>
      4 #include <stack>
      5 using namespace std;
      6 
      7 int n;
      8 const int size = 110;
      9 struct graph
     10 {
     11     int num;
     12     int next[size-10];
     13 }node[size];
     14 int val[size];
     15 int sum[size];
     16 int path[size];
     17 bool vis[size];
     18 queue<int>q;
     19 stack<int>s;
     20 
     21 void init( )
     22 {
     23     while( !q.empty() )
     24         q.pop();
     25     for( int i = 0 ; i<size-5 ; i++ )
     26         node[i].num = 0;
     27     memset( vis , false , sizeof(vis) );
     28     memset( sum , 0 , sizeof(sum) );
     29     memset( path , -1 , sizeof(path) );
     30 }
     31 
     32 void spfa( )
     33 {
     34     int now , point;
     35     q.push(1);
     36     vis[1] = true;
     37     while( !q.empty() )
     38     {
     39         now = q.front();
     40         q.pop();
     41         for( int i = 0 ; i<node[now].num ; i++ )
     42         {
     43             point = node[now].next[i];
     44             if( sum[now] + val[point] >= sum[point] )
     45             {
     46                 sum[point] = sum[now] + val[point];
     47                 path[point] = now;
     48                 if( !vis[point] )
     49                 {
     50                     vis[point] = true;
     51                     q.push(point);
     52                 }
     53             }
     54         }
     55         vis[now] = false;
     56     }
     57 }
     58 
     59 void output( )
     60 {
     61     s.push( n+1 );
     62     for( int i = path[n+1] ; i!=-1 ; i=path[i] )
     63     {
     64         s.push( i );
     65     }
     66     while( !s.empty( ) )
     67     {
     68         if( s.top() == n+1 )
     69         {
     70             cout << 1;
     71         }
     72         else
     73         {
     74             cout << s.top( ) << "->";
     75         }
     76         s.pop();
     77     }
     78     cout << endl;
     79 }
     80 
     81 int main()
     82 {
     83     int t , m , cnt , x , y , num;
     84     while( cin >> t )
     85     {
     86         cnt = 1;
     87         for( int k = 1 ; k<=t ; k++ )
     88         {
     89             init();
     90             cin >> n; // n+1个结点
     91             for( int i = 1 ; i<=n ; i++ )
     92             {
     93                 cin >> val[i];
     94             }
     95             val[n+1] = 0;
     96             cin >> m;
     97             while( m-- ) // m对关系
     98             {
     99                 cin >> x >> y;
    100                 num = node[x].num;
    101                 node[x].next[ node[x].num++ ] = y;
    102             }
    103             spfa();
    104             cout << "CASE " << cnt++ << "#" << endl;
    105             cout << "points " << ": " << sum[n+1] << endl;
    106             cout << "circuit : ";
    107             output( );
    108             if(k<t)
    109                 cout << endl;
    110         }
    111     }
    112     return 0;
    113 }
    View Code

    这几天 正好不出去玩 看了好多部电影--推荐几部--意外 -古天乐  单身男女--古天乐 窃听风云 1 2 3 大概就看了这5部吧

    写完这个去看下 孤男寡女--刘德华  然后晚上来写下它的dp版本=-=

    这个的dp真的狠简单 我都觉得和我写的spfa没有太大区别 就是spfa弄了个队列优化的感觉....

    它的状态方程dp[ j ] = max( dp[ j ] , dp[ i ]  + val[ j ] )就是对应我spfa里以前所谓的 松弛 操作... 写起来很快 所以

     1 #include <iostream>
     2 #include <cstring>
     3 #include <stack>
     4 using namespace std;
     5 
     6 int n;
     7 const int size = 110;
     8 bool mp[size][size];
     9 int path[size];
    10 int val[size];
    11 int dp[size];
    12 stack<int>s;
    13 
    14 void init()
    15 {
    16     memset( dp , 0 , sizeof(dp) );
    17     memset( mp , false , sizeof(mp) );
    18     memset( path , -1 , sizeof(path) );
    19 }
    20 
    21 void solve( )
    22 {
    23     for( int i = 1 ; i<=n ; i++ )
    24     {
    25         for( int j = i+1 ; j<=n+1 ; j++ )
    26         {
    27             if( mp[i][j] )
    28             {
    29                 if( dp[j] <= dp[i] + val[j] )
    30                 {
    31                     path[j] = i;
    32                     dp[j] = dp[i] + val[j];
    33                 }
    34             }
    35         }
    36     }
    37 }
    38 
    39 void output( )
    40 {
    41     s.push( n+1 );
    42     for( int i = path[n+1] ; i!=-1 ; i = path[i] )
    43     {
    44         s.push( i );
    45     }
    46     while( !s.empty() )
    47     {
    48         if( s.top() == n+1 )
    49         {
    50             cout << 1 << endl;
    51         }
    52         else
    53         {
    54             cout << s.top( ) << "->";
    55         }
    56         s.pop();
    57     }
    58 }
    59 
    60 int main()
    61 {
    62     int t , m , x, y;
    63     while( cin >> t )
    64     {
    65         for( int k = 1 ; k<=t ; k++ )
    66         {
    67             init( );
    68             cin >> n;
    69             for( int i = 1 ; i<=n ; i++ )
    70             {
    71                 cin >> val[i];
    72             }
    73             val[n+1] = 0;
    74             cin >> m;
    75             while( m-- )
    76             {   
    77                 cin >> x >> y;
    78                 mp[x][y] = true;
    79             }
    80             solve( );
    81             cout << "CASE " << k << "#" << endl;
    82             cout << "points " << ": " << dp[n+1] << endl;
    83             cout << "circuit : ";
    84             output( );
    85             if(k<t)
    86                 cout << endl;
    87         }
    88     }
    89     return 0;
    90 }
    View Code

    today:

      我这一生遇到过很多人 他们如同指间的烟火 忽明忽暗 最后只沦为一抹灰烬

      而你不同 你如北斗 闪耀在我的整个人生

    just follow your heart
  • 相关阅读:
    51Nod 1007 正整数分组(01背包)
    二叉树层次遍历(以先序输入)
    HttpContext.Current.Request.Url
    SqlDataReader和SqlDataAdapter的区别
    DataSet和DataTable详解
    DataTable和DataSet什么区别
    Git 忽略
    hack速查表
    ie6常见css bug
    详说 IE hasLayout
  • 原文地址:https://www.cnblogs.com/radical/p/3878471.html
Copyright © 2020-2023  润新知