zoukankan      html  css  js  c++  java
  • HDU 2433 (最短路+BFS+剪枝)

    http://acm.hdu.edu.cn/showproblem.php?pid=2433

    这个问题因为路径都是1,所以可以用bfs遍历

    可以看这几篇文章讲解:

    http://blog.csdn.net/panyanyany/article/details/7215069

    (这篇代码非常清晰,而且效率很高)

    http://www.cppblog.com/keroro/archive/2013/05/27/200622.html?opt=admin

      1 #include <cstdio>
      2 #include <queue>
      3 #include <vector>
      4 using namespace std;
      5 
      6 #define MEM(a,v) memset (a,v,sizeof(a))
      7 // a for address, v for value
      8 
      9 #define max(x,y) ((x)>(y)?(x):(y))
     10 #define max(x,y) ((x)>(y)?(x):(y))
     11 
     12 const int L = 1010;
     13 const int INF = 1<<27;
     14 
     15 bool    used[L], bCnet, bInit ;
     16 int     n, m ;
     17 int     dist[L], map[L][L], sum_d[L], pre[L][L];
     18 
     19 
     20 //边表
     21 struct Edge
     22 {
     23           int u,v;
     24 };
     25 
     26 Edge e[30*L];
     27 
     28 
     29 int bfs(int beg)
     30 {
     31           MEM(used,false);
     32           MEM(dist,0);
     33 
     34           used[beg] = true;
     35 
     36           queue<int> q;
     37           q.push(beg);
     38 
     39           int i;
     40 
     41           while(!q.empty())
     42           {
     43                     int t = q.front();
     44                     q.pop();
     45                     for(i = 1;i<=n;i++)
     46                     {
     47                               if(!used[i] && map[t][i])
     48                               {
     49                                         used[i] = true;
     50                                         dist[i] = dist[t]+1;
     51 
     52                                         //初始化    bInit =true
     53                                         //初始化后  bfs = false
     54                                         if(bInit)
     55                                                   pre[beg][i] = t;
     56                                         //pre储存的是beg树里面,i的上一个元素
     57                                         //这样只需判断pre[x][u] ==v 和pre[x][v] == u
     58                                         //就可以知道x树里面有没有uv边
     59 
     60                                         q.push(i);
     61                               }
     62                     }
     63           }
     64 
     65           int sum = 0;
     66 
     67 
     68           //求出点beg到各边的距离和
     69           // 从 beg+1 开始 和从 1 开始,效果差不多
     70           for(i = beg+1;i<=n;i++)
     71           {
     72                     if(!dist[n])
     73                               return INF;
     74                     else
     75                               sum+=dist[i];
     76           }
     77           return sum;
     78 
     79 }
     80 
     81 
     82 
     83 int main()
     84 {
     85           int i,j;
     86 
     87           int u,v,sum,res;
     88 
     89           while(~scanf("%d%d",&n,&m))
     90           {
     91                     MEM(map,0);
     92                     MEM(pre,0);
     93 
     94                     for(i = 1;i<=m;i++)
     95                     {
     96                               scanf("%d%d",&u,&v);
     97                               map[u][v] = ++map[v][u];
     98 
     99                               //如果有重复边的话,map为2
    100 
    101                               e[i].u = v;
    102                               e[i].v = u;
    103                     }
    104 
    105                     sum = 0;
    106                     bInit = true;
    107                     bCnet = true;
    108 
    109 
    110                     //求出每个点到其他点的距离和
    111                     for(i = 1;i<=n;i++)
    112                     {
    113                               sum_d[i] = bfs(i);
    114                               sum+=sum_d[i];
    115 
    116                               if(sum>=INF)
    117                               {
    118                                         bCnet = false;
    119                                         break;
    120                               }
    121                     }
    122 
    123                     bInit = false;
    124 
    125 
    126                     //删除边
    127                     for(i = 1;i<=m;i++)
    128                     {
    129                               //uv为删除的边
    130                               u = e[i].u;
    131                               v = e[i].v;
    132 
    133                               // map[u][v] 判断有无重边,可以优化300多MS
    134                               if(bCnet && map[u][v] == 1)
    135                               {
    136                                         res = 0;
    137                                         for(j = 1;j<=n;j++)
    138                                         {
    139                                                   //j树里不存在删除的边
    140                                                   // 最重要的剪枝,否则直接超时
    141                                                   if(pre[j][u] != v && pre[j][v] !=u)
    142                                                   {
    143                                                             res += sum_d[j];
    144                                                   }
    145                                                   else
    146                                                   {
    147                                                             //存在uv边,j树重新bfs
    148                                                             --map[u][v];
    149                                                             --map[v][u];
    150                                                             res += bfs(j);
    151                                                             ++map[u][v];
    152                                                             ++map[v][u];
    153 
    154                                                             if(res >= INF)
    155                                                                       break;
    156 
    157                                                   }
    158 
    159                                         }
    160 
    161 
    162 
    163                               }
    164                               else
    165                                         res=sum;
    166 
    167                               if(res >= INF)
    168                                         puts("INF");
    169                               else
    170                                         printf("%d
    ",res*2);
    171 
    172                     }
    173 
    174 
    175           }
    176 
    177           return 0;
    178 }
  • 相关阅读:
    SQL server使用
    NCC 事务
    springboot学习
    容器
    x86汇编
    git之.gitignore文件用途
    Linux系统安装之U盘引导
    使用异步I/O大大提高应用程序的性能
    Python3.5 用 pip 安装lxml时出现 “Unable to find vcvarsall.bat ”?(转载)
    python之正则表达式
  • 原文地址:https://www.cnblogs.com/qlky/p/5018096.html
Copyright © 2011-2022 走看看