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\n",res*2);
171
172                     }
173
174
175           }
176
177           return 0;
178 }
时间: 2024-11-05 20:21:02

HDU 2433 (最短路+BFS+剪枝)的相关文章

hdu 4400 离散化+二分+BFS(暴搜剪枝还超时的时候可以借鉴一下)

Mines Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1110    Accepted Submission(s): 280 Problem Description Terrorists put some mines in a crowded square recently. The police evacuate all peo

hdu 2433 Travel (最短路径树)

hdu 2433 Travel Description One day, Tom traveled to a country named BGM. BGM is a small country, but there are N (N <= 100) towns in it. Each town products one kind of food, the food will be transported to all the towns. In addition, the trucks will

HDU 1242 -Rescue (双向BFS)&amp;&amp;( BFS+优先队列)

题目链接:Rescue 进度落下的太多了,哎╮(╯▽╰)╭,渣渣我总是埋怨进度比别人慢...为什么不试着改变一下捏.... 开始以为是水题,想敲一下练手的,后来发现并不是一个简单的搜索题,BFS做肯定出事...后来发现题目里面也有坑 题意是从r到a的最短距离,"."相当时间单位1,"x"相当时间单位2,求最短时间 HDU 搜索课件上说,这题和HDU1010相似,刚开始并没有觉得像剪枝,就改用  双向BFS   0ms  一Y,爽! 网上查了一下,神牛们竟然用BFS+

ACM: HDU 2544 最短路-Dijkstra算法

HDU 2544最短路 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗? Input 输入包括多组数据.每组数据第一行是两个整数N.M(N<=100,M<

hdu 1429 状压bfs

#include <iostream> #include <cstring> #include <string> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <map> #define inf 0x3f3f3f3f #define ll __in

hdu 2112 (最短路+map)

链接:http://acm.hdu.edu.cn/showproblem.php?pid=2112 HDU Today Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 14515    Accepted Submission(s): 3405 Problem Description 经过锦囊相助,海东集团终于度过了危机,从此,HDU的发

HDU 1242 Rescue(优先队列+bfs)

题目地址:HDU 1242 这个题相比于普通的bfs有个特殊的地方,经过士兵时会额外消耗时间,也就是说此时最先搜到的时候不一定是用时最短的了.需要全部搜一遍才可以.这时候优先队列的好处就显现出来了.利用优先队列,可以让队列中的元素按时间排序,让先出来的总是时间短的,这样的话,最先搜到的一定是时间短的,就不用全部搜一遍了.PS:我是为了学优先队列做的这题..不是为了这题而现学的优先队列.. 代码如下: #include <iostream> #include <stdio.h> #i

HDU 2544 最短路(我的dijkstra算法模板、SPAFA算法模板)

思路:这道题是基础的最短路径算法,可以拿来试一下自己对3种方法的理解 dijkstra主要是从第一个点开始枚举,每次枚举出当当前最小的路径,然后再以那最小的路径点为起点,求出它到其它未标记点的最短距离 bellman-ford 算法则是假设有向网中有n 个顶点.且不存在负权值回路,从顶点v1 和到顶点v2 如果存在最短路径,则此路径最多有n-1 条边.这是因为如果路径上的边数超过了n-1 条时,必然会重复经过一个顶点,形成回路:而如果这个回路的权值总和为非负时,完全可以去掉这个回路,使得v1到v

hdu 4849 最短路 西安邀请赛 Wow! Such City!

http://acm.hdu.edu.cn/showproblem.php?pid=4849 会有很多奇怪的Wa的题,当初在西安就不知道为什么wa,昨晚做了,因为一些Sb错误也wa了很久,这会儿怎么写都会AC.... 收获: 1.还是基本都构思好在去敲代码,因为当时没过,昨晚心里有阴影,敲得很慢,而且最开始各种取模以防止漏掉,太保守了......以后一定先估算是不是需要取模防止TLE,当然时间够的话还是适当多取个模防止莫名其妙的错误.. 2.如果出错,注意参数是不是对的,最开始写好之后,因为m和