const int INF=0x3f3f3f3f;——ACM中的无穷大常量

在算法竞赛中,常量0x3f3f3f3f被广泛用作“无穷大”的表示,其十进制值为1061109567,与INT_MAX处于同一数量级。该数值的优势在于即使翻倍也不易发生溢出,并且能够直接通过memset初始化数组。

0x3f3f3f3f 0x开头的 是十六进制常数, 等于 十进制 1061109567
等于 二进制: 00111111 00111111 00111111 00111111

const int inf=0x3f3f3f3f -- 声明 inf 是 const int型 , const 表示 inf 一旦有了值以后就不允许(通过赋值 来)改变它的值.

 

在算法竞赛中,我们常常需要用到设置一个常量用来代表“无穷大”

比如对于int类型的数,有的人会采用INT_MAX,即0x7fffffff作为无穷大。但是以INT_MAX为无穷大常常面临一个问题,即加一个其他的数会溢出。

而这种情况在动态规划,或者其他一些递推的算法中常常出现,很有可能导致算法出问题。

所以在算法竞赛中,我们常采用0x3f3f3f3f来作为无穷大。0x3f3f3f3f主要有如下好处:

  • 0x3f3f3f3f的十进制为1061109567,和INT_MAX一个数量级,即10^9数量级,而一般场合下的数据都是小于10^9的。
  • 0x3f3f3f3f * 2 = 2122219134,无穷大相加依然不会溢出。
  • 可以使用memset(array, 0x3f, sizeof(array))来为数组设初值为0x3f3f3f3f,因为这个数的每个字节都是0x3
在代码 `const int inf = 0x3f3f3f3f;` 中,`const` 关键字用于定义常量,意味着该变量一旦被赋值就不能再被修改。`int` 表示变量的类型为整数。`0x3f3f3f3f` 是一个十六进制的数值,将其转换为十进制是 `1061109567`。 其用途主要体现在以下几个方面: - **初始化距离或权值**:在图论算法中,如 Dijkstra 算法、Floyd-Warshall 算法等,常常需要对距离数组进行初始化,将所有距离初始化为一个极大值,表示初始时这些节点之间的距离是未知的或者是无穷远的。由于 `0x3f3f3f3f` 是一个足够大的数,并且在进行加法运算时不容易溢出,所以可以作为一个合适的初始值。例如在引用[3]中,`fill(dp, dp + N, inf);` 就是将 `dp` 数组初始化为 `inf`,用于存储从起点到各个节点的最短距离。 - **比较和更新**:在算法中,当需要比较和更新某些值时,使用 `0x3f3f3f3f` 作为初始值可以方便地进行比较和更新操作。例如在寻找最小值的过程中,初始将最小值设为 `inf`,然后在遍历过程中不断更新这个最小值。 以下是引用[3]中使用 `inf` 的部分代码示例: ```cpp #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<cstdio> #include<queue> #include<vector> using namespace std; const int N = 1111; const int inf = 0x3f3f3f3f; int vis[N],dp[N]; struct P { int c,v; P(int c,int v):c(c),v(v){} P(){} bool operator < (const P& t1)const { return c>t1.c; } }; priority_queue<P>que; vector<P>vec[N]; int n,m; int main() { int i,j,u,v,c; scanf("%d%d",&m,&n); while(m--) { scanf("%d%d%d",&u,&v,&c); vec[u].push_back(P(c,v)); vec[v].push_back(P(c,u)); } fill(dp,dp+N,inf); // 将 dp 数组初始化为 inf P p = P(0,1); dp[1]=0; que.push(p); while(!que.empty()) { p = que.top(); que.pop(); if(vis[p.v]) continue; vis[p.v]=1; for(i=0;i<vec[p.v].size();i++) { P tmp = vec[p.v][i]; if(dp[tmp.v]>dp[p.v]+tmp.c) { dp[tmp.v]=dp[p.v]+tmp.c; que.push(P(dp[tmp.v],tmp.v)); } } } printf("%d\n",dp[n]); return 0; } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值