当前位置 : 主页 > 编程语言 > c语言 >

poj-2492

来源:互联网 收集:自由互联 发布时间:2023-09-03
//16852K 6313MS G++ #include cstdio #include queue #include cstring using namespace std; #define MAX 2010 char interactionReleation[MAX][MAX]; char interactionCheckFlag[MAX][MAX]; char genderInfo[MAX]; // the gender of bug 0, not checked, 1
//16852K    6313MS  G++ 

 #include <cstdio> 

 #include <queue> 

 #include <cstring> 


 using namespace std; 


 #define MAX 2010 


 char interactionReleation[MAX][MAX]; 

 char interactionCheckFlag[MAX][MAX]; 


 char genderInfo[MAX]; // the gender of bug 0, not checked, 1 male /-1 female 

 char bugCheckFlag[MAX]; 


 struct Bug { 

     char gender; // 0, not checked, 1 /-1 assume bug1 gender is 1(-1 is oK too, just need the difference of gender) 

     int bugId; 

 }; 


 typedef struct Bug Bug; 


 queue<Bug> bugQueue; 


 int bugNum; 

 int interactionNum; 


 char BFS(int beginBug) { 

     while(bugQueue.size()) { 

         bugQueue.pop(); 

     } 


     Bug bug1; 

     bug1.gender = 1; 

     bug1.bugId = beginBug; 

     bugQueue.push(bug1); 

     genderInfo[beginBug] = 1; 

     bugCheckFlag[beginBug] = 1; 


     while(bugQueue.size()) { 

         Bug curBug = bugQueue.front(); 

         int curBugId = curBug.bugId; 

         int curBugGender = curBug.gender; 

          

         bugQueue.pop(); 

         for (int i = 1; i <= bugNum; i++) { // check the bugs interact with cur bug 

             // if this bug interact with curBug 

             if (interactionReleation[curBugId][i] && 

                 !interactionCheckFlag[curBugId][i] && 

                 !interactionCheckFlag[i][curBugId]) { 

                 interactionCheckFlag[curBugId][i] = 1; // this interact has been checked 

                 interactionCheckFlag[i][curBugId] = 1; // this interact has been checked 

                 bugCheckFlag[i] = 1; 

                 if (genderInfo[i] == 0)  {// this bug is not checked yet 

                     genderInfo[i] = -curBugGender; // interact, must be reverse gender 

                 } else if (genderInfo[i] == curBugGender) { // homosexual! 

                     return 1; 

                 } 

                 Bug nextBug; 

                 nextBug.gender = genderInfo[i]; 

                 nextBug.bugId = i; 

                 bugQueue.push(nextBug); 

             } 

         } 

     } 

     return 0; 

 } 


 char checkBugs() { 

     for (int i = 1; i <= bugNum; i++) { 

         if (!bugCheckFlag[i]) {// if not checked 

             if (BFS(i)) { // if 

                 return 1; 

             } 

         } 

     } 

     return 0; 

 } 


 int main() { 

     int caseNum; 

     scanf("%d", &caseNum); 

     for (int i = 0; i < caseNum; i++) { 

         memset(interactionReleation, 0, sizeof(interactionReleation)); 

         memset(interactionCheckFlag, 0, sizeof(interactionCheckFlag)); 

         memset(genderInfo, 0, sizeof(genderInfo)); 

         memset(bugCheckFlag, 0, sizeof(bugCheckFlag)); 

         bugNum = 0; 

         interactionNum = 0; 

         scanf("%d %d", &bugNum, &interactionNum); 

         for (int j = 0; j < interactionNum; j++) { 

             int bug1, bug2; 

             scanf("%d %d", &bug1, &bug2); 

             interactionReleation[bug1][bug2] = 1; 

             interactionReleation[bug2][bug1] = 1; 

         } 

         printf("Scenario #%d:\n", i+1); 

         if (!checkBugs()) { 

             printf("No suspicious bugs found!\n\n"); 

         } else { 

             printf("Suspicious bugs found!\n\n"); 

         } 

     } 
}

16852K    6313MS  G++.... 

速度很慢,这道题好的解法其实是并查集,不过因为做这道题时,分类是搜索,因此就用了BFS, 时间就不care了。

题目要求找到的是是否有同性恋bug,

判断的标准就是,同样gender的bug交配了,那么就必然有同性恋蟑螂。

用BFS的思路,就是现从某一个bug作为第一个节点开始进行广度遍历,为第一个bug指定一个gender(公母都无所谓,因为是彼此对称的),

然后其相邻的节点(也就是与此bug交配的其他bug)的gender就应该是此相反的gender,

要注意的是,一般的BFS是遍历所有的节点,而本体则要求遍历所有的边(因为我们check的是bug之间的交配,就是bug之间的边),

所以相应的flag二维矩阵就要存储每个边是否被遍历过,

在从某个节点遍历其他的节点时,即从一个bug(A)考察与它交配的其他bug(B)时,

会有3个case:

case1: B节点是第一次被遍历到,那么B的gender就置为A的相反gender

case2:  B在之前已经通过其他bug的交配关系(即其他的边)被遍历过,B的gender与A的gender相反,这是正确的情况,继续遍历边即可。

case3: 同case2,但是B的gender与A的gender一样,那么A与B中必有同性恋bug,直接return 退出BFS 输出结果即可。


要注意的几点:

1.搞一个数组来保存bug的gender,这样才能在需要的时候根据bug的id取得其gender

2. 要注意,不一定只有一个图,而是可能会有好几个独立的连通图,对每个图都要bfs

比如:

5个bug

1-2

3-.4

4-5

3-5

1和2组成一个独立图, 3,4,5组成一个独立图

要对每个连通图进行check,只有每个图都没有同性恋,才算完全没有。

因此要搞一个flag数组标示某个bug是否被check过,一直对没有被check过的bug进行上面的check,直到所有的bug都被check过了。

这道题本质就是遍历+染色,只不过这里要判断染色冲突,染色规则也是特定的(相邻节点颜色相反).

【文章出处:日本大带宽服务器 http://www.558idc.com/jap.html 欢迎留下您的宝贵建议】
上一篇:poj-1065
下一篇:没有了
网友评论