布尔变量自动改变其值
Boolean variable is automatically changing its value
这个问题来自SPOJ。我被要求找出这个图是否是双部的。我用BFS来找它。这里的问题是在//PROBLEM COMING HERE
节下的while循环中(请参阅下面的代码以查找此语句)
问题描述:
我想在0和1之间切换。所以我选择了一个叫做flag
的bool
值,并用0初始化它。现在,每次迭代我都要切换它的值。所以我用了flag = !flag
。然而,由于某些未知的原因,在执行语句flag = ! flag
之前,标志值在第一次迭代之后自动切换。因此,很多问题随之而来。
//BUG LIFE
#include <cstdio>
#include <vector>
#include <queue>
#define DEFAULT 2
using namespace std;
int main()
{
int t,n,e;
bool eflag;
//freopen("input.txt", "r", stdin);
//Taking the Testcase
scanf("%d",&t);
//Iterating each Testcase
for(int itr=1; itr<=t; itr++)
{
//n is the number of nodes in the graph and e is the no of edges.
scanf("%d %d",&n,&e);
//eflag is exit flag in short. this is used to early exit to save time if we already found out that the given graph isn't bi-partite.
//Assuming the graph is bi-partite hence eflag = false meaning no exit is required yet.
eflag = false;
//Graph data structure vector 2D Array
vector < vector < int > > graph(n+1);
//Taking edges as input and adding in the graph
for(int i = 1; i <=e; i++)
{
int v1,v2;
scanf("%d %d",&v1,&v2);
graph[v1].push_back(v2);
graph[v2].push_back(v1);
}
//Check the graph is bi-partite or not
//vis is an array which will hold whether a node has been explored or not. label is an array which segregates all the nodes in two groups 0 or 1.
bool vis[n+1]; int label[n+1];
//Initialising vis and label.
for(int i=1; i<=n; i++)
{
vis[i] = 0;
//DEFALUT VALUE IS 2. This is to tell that label of the node i hasn't been given yet or in otherwords, it's not be put in a group yet.
label[i] = DEFAULT;
}
//Taking nodes one by one and doing a BFS on it.
//LOGIC Here is: Take a node assign it a label 0 and add all the children of it in the queue and give them label 1. Now explore all children and give their children label 0. So like this, we alternate between labels.
//Now if we see that a node already has a label apart from 2 and a children is trying to label it with something different label it will mean that specific node is involved in both the groups. Hence we will set the eflag as true.
for(int i=1; i<=n && !eflag; i++)
{
if(!graph[i].empty() && !vis[i])
{
//Initialising the queue and adding the first node which has children.
queue <int> q;
q.push(i); bool flag;
//PROBLEM COMING HERE
//Assigning the label for this node as 0. meaning group 0
label[i] = 0; flag = false;
//BFS Starts
while(!q.empty() && !eflag)
{
int x = q.front(); q.pop();
printf("%d **n",flag);
//The children of this node needs to have different label than parent. Hence flag = !flag
flag = !flag;
printf("%d %dn",x,flag);
if(vis[x]) continue;
vis[x] = 1;
//Exploring the children and assigning them labels
for(vector <int>::iterator it = graph[x].begin(); it != graph[x].end(); it++)
{
//If the children doesn't have a default label and the label which it has is different than the one the parent is trying to put then it means that this child belongs to both the groups 0 and 1. So exit.
if(label[*it] != DEFAULT && label[*it] != flag)
{
printf("%d %d %d %dn",x,*it,label[*it],flag);
eflag = true;
break;
}
else
{
label[*it] = flag;
}
}
printf("asd %d **n",flag);
}
//PROBLEM ENDS HERE
}
}
if(eflag == false)
printf("Scenario #%d:nNo suspicious bugs found!n",itr);
else
printf("Scenario #%d:nSuspicious bugs found!n",itr);
}
return 0;
}
输出:0 **
1 1
asd 1 **
0 **
2 1
2 1 0 1
asd 1 **
Scenario #1:
Suspicious bugs found!
示例输入:
1
3 3
1 2
2 3
1 3
你在评论中的假设:
在输出asd 1**之后,它应该再次输出1**,因为flag = !Flag还没有被执行。但是它显示0 **
是错误的。(不是假设flag = ! flag
没有被执行,这是正确的。)
在下面的代码片段中,我删除了大部分不相关的代码(不用谢)。让我们命名一些循环:
for(int i=1; i<=n && !eflag; i++) // outer loop
{
// ..
queue <int> q;
q.push(i); bool flag;
label[i] = 0; flag = false; // (1)
while(!q.empty() && !eflag) // inner loop
{
int x = q.front(); q.pop();
printf("%d **n",flag); // (2)
flag = !flag;
printf("%d %dn",x,flag);
// ...
printf("asd %d **n",flag); // (3)
}
// ...
}
只能将一个元素压入q
。这是外环的顶部。你总是在内循环的顶部弹出它。只有当队列不为空时,内循环条件才为真。因此,对于每个外部循环,内部循环总是最多运行一次。因为内循环不会重复超过一次,所以在内循环(3)结束时打印asd 1**
后,总是跳转到外循环的开始。在外循环(1)的顶部,分配flag = false
。因此,无论flag
在(3)处的值是多少,它在(2)处的值始终是false
。
正如你所看到的,变量没有"自动"改变,也没有因为"未知的原因"改变。它在变化,因为你把它赋值到(1)
相关文章:
- 变量没有改变?通过向量的函数调用
- 在向量内更改变量的值不会改变其在向量外的值
- C++11:具有互斥锁的线程看到原子变量的值发生变化,尽管这是唯一可以改变它的代码
- 为什么我可以改变常量对象中的成员变量,这是返回常量对象函数的结果?
- 标准在哪里定义了可变变量可以改变
- C++11:可变的 lambda 似乎没有改变变量?
- printf() 似乎改变了一个变量
- 为什么我的变量在单独的线程中修改时没有改变?C++/boost
- 为什么 Player.x 和 Player.y 变量没有改变?
- C - 如何将各处的静态函数称为改变其私有变量
- 即使"friend class rect"在平方类中被评论,为什么它要改变矩形类的私有变量?
- 为什么调用 CUDA 内核函数时这个类成员变量没有改变
- 全局变量的顺序会改变C /OpenGL的性能
- 为什么一个函数的末尾有常量这个词,即使它确实改变了一个变量
- 如何在C++中改变超类和子类的变量
- setRoomName不会改变变量roomName
- 不能改变变量的值
- 是否有一种方法可以改变变量在内存中的存储方式(位大小)
- Std::cout改变变量的值
- 使用引用改变变量的地址