<?xml version="1.0" encoding="UTF-8"?>

<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
	<channel>
		<title>cpper编程论坛 - Blog</title>
		<link>http://www.cpper.com/c/blog.php</link>
		<description />
		<language>zh-CN</language>
		<lastBuildDate>Thu, 28 Aug 2008 04:52:02 GMT</lastBuildDate>
		<generator>vBulletin</generator>
		<ttl>60</ttl>
		<image>
			<url>http://www.cpper.com/c/images/misc/rss.jpg</url>
			<title>cpper编程论坛 - Blog</title>
			<link>http://www.cpper.com/c/blog.php</link>
		</image>
		<item>
			<title>急问！udp传输速率</title>
			<link>http://www.cpper.com/_rockets/131.html</link>
			<pubDate>Thu, 14 Aug 2008 02:58:25 GMT</pubDate>
			<description><![CDATA[wywajlj 794 113 2 365 

发信人: wywajlj(五台兄), 信区: NetPRG
标  题: 急问！！udp传输速率
发信站: 瀚海星云 (2008年08月14日10:19:43 星期四), 站内信件 WWWPOST

鄙人在100Mb/s的局域以太网测试时得到tcp的传输速率为：89Mb/s，而udp只有88Mb/s.
按理说这是不正常的，udp的传输速率应该高于tcp，请哪位大虾指教一下。代码如下

代码功能：从客户方向服务方传送数据，测试局域以太网路的传输速率

客户方：

代码:
---------
#include <stdio.h>
#include "winsock2.h"
#pragma  comment(lib,"Ws2_32.lib")

#define  RECV_IP    "192.168.168.13"
#define  BLOCK       65504
#define  NUM         10000*BLOCK

void main() {
  
  WSADATA wsaData;
  SOCKET SendSocket;
  sockaddr_in RecvAddr;
  int Port = 27015;
  char SendBuf[BLOCK];
  int BufLen = BLOCK;

  //---------------------------------------------
  // Initialize Winsock
  WSAStartup(MAKEWORD(2,2), &wsaData);

  //---------------------------------------------
  // Create a socket for sending data
  SendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

  //---------------------------------------------
  // Set up the RecvAddr structure with the IP address of
  // the receiver (in this example case "192.168.168.13")
  // and the specified port number.
  RecvAddr.sin_family = AF_INET;
  RecvAddr.sin_port = htons(Port);
  RecvAddr.sin_addr.s_addr = inet_addr(RECV_IP);
  
  //---------------------------------------------
  // Set up the buffer of SendSocket
  int nSendBuf=512*1024;//设置为32K
  int nret =setsockopt(SendSocket,SOL_SOCKET,SO_SNDBUF,(const char*)
&nSendBuf,sizeof(int));
  if (nret ==SOCKET_ERROR){
      printf("Set Buffer with error:%d\n",GetLastError());
      return;
  }
  //---------------------------------------------
  // Send a datagram to the receiver
  printf("Sending a datagram to the receiver...\n");
  int num =NUM,sendbytes;
  
  // Get the time beginning to send a datagram
  SYSTEMTIME systime;
  GetLocalTime(&systime);  //Get local time 
  printf("发送时间是:\n");
  printf("systime.wHour:%d\nsystime.wMinute:%d\nsystime.wSecond:%
d\nsystime.wMilliseconds:%d\n",
             
systime.wHour,systime.wMinute,systime.wSecond,systime.wMilliseconds);
        
  float t1 =(float)(3600*systime.wHour +60*systime.wMinute +systime.wSecond 
+0.001*systime.wMilliseconds);
  while (num >=0){
      sendbytes =sendto(SendSocket, SendBuf, BufLen, 0, 
      (SOCKADDR *) &RecvAddr, sizeof(RecvAddr));
      if (sendbytes <0){
          printf("send data with error:%d\n",GetLastError());
      }
      num =num -sendbytes;
  }

  //---------------------------------------------
  // When the application is finished sending, close the socket.
  printf("Finished sending. Closing socket.\n");

  // Get the time when sending is over
  GetLocalTime(&systime);       //local time 
  printf("接收时间：\n");
  printf("systime.wHour:%d\nsystime.wMinute:%d\nsystime.wSecond:%
d\nsystime.wMilliseconds:%d\n",
             
systime.wHour,systime.wMinute,systime.wSecond,systime.wMilliseconds);


  float t2 =(float)(3600*systime.wHour +60*systime.wMinute +systime.wSecond 
+0.001*systime.wMilliseconds);
  float t =t2-t1;
  float v = (float)((float)(NUM*8.00)/(1024.00*1024.00*t));
  printf("Time spended in sending datagram:%fseconds\n",t);
  printf("传输速率：%fMb/s\n",v);
  closesocket(SendSocket);

  //---------------------------------------------
  // Clean up and quit.
  printf("Exiting.\n");
  WSACleanup();
  return;
}
---------
服务方代码：

代码:
---------
#include <stdio.h>
#include "winsock2.h"
#pragma  comment(lib, "Ws2_32.lib")

#define BLOCK  65504
#define NUM    10000*BLOCK

void main() {

  WSADATA wsaData;
  SOCKET RecvSocket;
  sockaddr_in RecvAddr;
  int Port = 27015;
  char RecvBuf[BLOCK];
  int  BufLen = BLOCK;
  sockaddr_in SenderAddr;
  int SenderAddrSize = sizeof(SenderAddr);
  int RecvAddrSize = sizeof(RecvAddr);

  //-----------------------------------------------
  // Initialize Winsock
  WSAStartup(MAKEWORD(2,2), &wsaData);

  //-----------------------------------------------
  // Create a receiver socket to receive datagrams
  RecvSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

  //-----------------------------------------------
  // Bind the socket to any address and the specified port.
  RecvAddr.sin_family = AF_INET;
  RecvAddr.sin_port = htons(Port);
  RecvAddr.sin_addr.s_addr = inet_addr("192.168.168.13");

  bind(RecvSocket, (SOCKADDR *) &RecvAddr, sizeof(RecvAddr));


  // Initialize the SendAddr struct
 
  SenderAddr.sin_family = AF_INET;
  SenderAddr.sin_port = htons(Port);
  SenderAddr.sin_addr.s_addr = inet_addr("192.168.168.44");

  

  //-----------------------------------------------
  //设置接受缓冲区
  int nRecvBuf =512*1024 ;   //设置缓冲区
  int nret =setsockopt(RecvSocket, SOL_SOCKET, SO_RCVBUF,(const char *)
&nRecvBuf, sizeof (int));
  if (nret ==SOCKET_ERROR){
      printf("set receive buffer with error:%d\n",GetLastError());
  }

  //-----------------------------------------------
  // Call the recvfrom function to receive datagrams
  // on the bound socket.
  printf("Receiving datagrams...\n");
  int num =NUM;
  int recvbytes;
  while (num >=0){
      recvbytes =recvfrom(RecvSocket, RecvBuf, BufLen, 0, 
      (SOCKADDR *)&SenderAddr, &SenderAddrSize);
      if (recvbytes <0){
          printf("receive data with error:%d\n",GetLastError());
      }
      //printf("%d\n",recvbytes);
      num =num -recvbytes;
  }

  //-----------------------------------------------
  // Close the socket when finished receiving datagrams
  printf("Finished receiving. Closing socket.\n");
  closesocket(RecvSocket);

  //-----------------------------------------------
  // Clean up and exit.
  printf("Exiting.\n");
  WSACleanup();
  return;
}
---------
]]></description>
			<content:encoded><![CDATA[<div>wywajlj 794 113 2 365 <br />
<br />
发信人: wywajlj(五台兄), 信区: NetPRG<br />
标  题: 急问！！udp传输速率<br />
发信站: 瀚海星云 (2008年08月14日10:19:43 星期四), 站内信件 WWWPOST<br />
<br />
鄙人在100Mb/s的局域以太网测试时得到tcp的传输速率为：89Mb/s，而udp只有88Mb/s.<br />
按理说这是不正常的，udp的传输速率应该高于tcp，请哪位大虾指教一下。代码如下<br />
<br />
代码功能：从客户方向服务方传送数据，测试局域以太网路的传输速率<br />
<br />
客户方：<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">代码:</div>
	<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:auto; height:1522px; overflow:auto"><div dir="ltr" style="text-align:left;">#include &lt;stdio.h&gt;
#include &quot;winsock2.h&quot;
#pragma  comment(lib,&quot;Ws2_32.lib&quot;)

#define  RECV_IP    &quot;192.168.168.13&quot;
#define  BLOCK       65504
#define  NUM         10000*BLOCK

void main() {
  
  WSADATA wsaData;
  SOCKET SendSocket;
  sockaddr_in RecvAddr;
  int Port = 27015;
  char SendBuf[BLOCK];
  int BufLen = BLOCK;

  //---------------------------------------------
  // Initialize Winsock
  WSAStartup(MAKEWORD(2,2), &amp;wsaData);

  //---------------------------------------------
  // Create a socket for sending data
  SendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

  //---------------------------------------------
  // Set up the RecvAddr structure with the IP address of
  // the receiver (in this example case &quot;192.168.168.13&quot;)
  // and the specified port number.
  RecvAddr.sin_family = AF_INET;
  RecvAddr.sin_port = htons(Port);
  RecvAddr.sin_addr.s_addr = inet_addr(RECV_IP);
  
  //---------------------------------------------
  // Set up the buffer of SendSocket
  int nSendBuf=512*1024;//设置为32K
  int nret =setsockopt(SendSocket,SOL_SOCKET,SO_SNDBUF,(const char*)
&amp;nSendBuf,sizeof(int));
  if (nret ==SOCKET_ERROR){
      printf(&quot;Set Buffer with error:%d\n&quot;,GetLastError());
      return;
  }
  //---------------------------------------------
  // Send a datagram to the receiver
  printf(&quot;Sending a datagram to the receiver...\n&quot;);
  int num =NUM,sendbytes;
  
  // Get the time beginning to send a datagram
  SYSTEMTIME systime;
  GetLocalTime(&amp;systime);  //Get local time 
  printf(&quot;发送时间是:\n&quot;);
  printf(&quot;systime.wHour:%d\nsystime.wMinute:%d\nsystime.wSecond:%
d\nsystime.wMilliseconds:%d\n&quot;,
             
systime.wHour,systime.wMinute,systime.wSecond,systime.wMilliseconds);
        
  float t1 =(float)(3600*systime.wHour +60*systime.wMinute +systime.wSecond 
+0.001*systime.wMilliseconds);
  while (num &gt;=0){
      sendbytes =sendto(SendSocket, SendBuf, BufLen, 0, 
      (SOCKADDR *) &amp;RecvAddr, sizeof(RecvAddr));
      if (sendbytes &lt;0){
          printf(&quot;send data with error:%d\n&quot;,GetLastError());
      }
      num =num -sendbytes;
  }

  //---------------------------------------------
  // When the application is finished sending, close the socket.
  printf(&quot;Finished sending. Closing socket.\n&quot;);

  // Get the time when sending is over
  GetLocalTime(&amp;systime);       //local time 
  printf(&quot;接收时间：\n&quot;);
  printf(&quot;systime.wHour:%d\nsystime.wMinute:%d\nsystime.wSecond:%
d\nsystime.wMilliseconds:%d\n&quot;,
             
systime.wHour,systime.wMinute,systime.wSecond,systime.wMilliseconds);


  float t2 =(float)(3600*systime.wHour +60*systime.wMinute +systime.wSecond 
+0.001*systime.wMilliseconds);
  float t =t2-t1;
  float v = (float)((float)(NUM*8.00)/(1024.00*1024.00*t));
  printf(&quot;Time spended in sending datagram:%fseconds\n&quot;,t);
  printf(&quot;传输速率：%fMb/s\n&quot;,v);
  closesocket(SendSocket);

  //---------------------------------------------
  // Clean up and quit.
  printf(&quot;Exiting.\n&quot;);
  WSACleanup();
  return;
}</div></pre>
</div>服务方代码：<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">代码:</div>
	<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:auto; height:1298px; overflow:auto"><div dir="ltr" style="text-align:left;">#include &lt;stdio.h&gt;
#include &quot;winsock2.h&quot;
#pragma  comment(lib, &quot;Ws2_32.lib&quot;)

#define BLOCK  65504
#define NUM    10000*BLOCK

void main() {

  WSADATA wsaData;
  SOCKET RecvSocket;
  sockaddr_in RecvAddr;
  int Port = 27015;
  char RecvBuf[BLOCK];
  int  BufLen = BLOCK;
  sockaddr_in SenderAddr;
  int SenderAddrSize = sizeof(SenderAddr);
  int RecvAddrSize = sizeof(RecvAddr);

  //-----------------------------------------------
  // Initialize Winsock
  WSAStartup(MAKEWORD(2,2), &amp;wsaData);

  //-----------------------------------------------
  // Create a receiver socket to receive datagrams
  RecvSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

  //-----------------------------------------------
  // Bind the socket to any address and the specified port.
  RecvAddr.sin_family = AF_INET;
  RecvAddr.sin_port = htons(Port);
  RecvAddr.sin_addr.s_addr = inet_addr(&quot;192.168.168.13&quot;);

  bind(RecvSocket, (SOCKADDR *) &amp;RecvAddr, sizeof(RecvAddr));


  // Initialize the SendAddr struct
 
  SenderAddr.sin_family = AF_INET;
  SenderAddr.sin_port = htons(Port);
  SenderAddr.sin_addr.s_addr = inet_addr(&quot;192.168.168.44&quot;);

  

  //-----------------------------------------------
  //设置接受缓冲区
  int nRecvBuf =512*1024 ;   //设置缓冲区
  int nret =setsockopt(RecvSocket, SOL_SOCKET, SO_RCVBUF,(const char *)
&amp;nRecvBuf, sizeof (int));
  if (nret ==SOCKET_ERROR){
      printf(&quot;set receive buffer with error:%d\n&quot;,GetLastError());
  }

  //-----------------------------------------------
  // Call the recvfrom function to receive datagrams
  // on the bound socket.
  printf(&quot;Receiving datagrams...\n&quot;);
  int num =NUM;
  int recvbytes;
  while (num &gt;=0){
      recvbytes =recvfrom(RecvSocket, RecvBuf, BufLen, 0, 
      (SOCKADDR *)&amp;SenderAddr, &amp;SenderAddrSize);
      if (recvbytes &lt;0){
          printf(&quot;receive data with error:%d\n&quot;,GetLastError());
      }
      //printf(&quot;%d\n&quot;,recvbytes);
      num =num -recvbytes;
  }

  //-----------------------------------------------
  // Close the socket when finished receiving datagrams
  printf(&quot;Finished receiving. Closing socket.\n&quot;);
  closesocket(RecvSocket);

  //-----------------------------------------------
  // Clean up and exit.
  printf(&quot;Exiting.\n&quot;);
  WSACleanup();
  return;
}</div></pre>
</div></div>

]]></content:encoded>
			<dc:creator>永远的Rockets</dc:creator>
			<guid isPermaLink="true">http://www.cpper.com/c/http://www.cpper.com/_rockets/131.html</guid>
		</item>
		<item>
			<title><![CDATA[It's Not a Bug, It's a Language Feature!]]></title>
			<link>http://www.cpper.com/bankrock/130.html</link>
			<pubDate>Sun, 27 Jul 2008 15:47:37 GMT</pubDate>
			<description><![CDATA[标题这句话是维护编程语言尊严的常用语，但有时候Language Feature比Bug还要可怕，今天鄙人就被C/C++的一个Language Feature和devc++耍了一把。
首先来看看这段代码：

struct SearchItem
{
    SearchItem(int impedanceSegId, int parentImpedSegId, int startingLoadId)
        : impedSegId(impedanceSegId), parImpedSegId(parentImpedSegId), startLoadId(startingLoadId)
    {  }

    int impedSegId, parImpedSegId, startLoadId;
};

void GetAccImpedAndMtrxStruct(....)
{
    deque<SearchItem> searchQueue;
     searchQueue.push_back(SearchItem(tree.rootImpedSegId, -1, 0));  //1

    while (!searchQueue.empty())
    {
        SearchItem& item = searchQueue.front();
        int impedSegId = item.impedSegId;
        int parImpedSegId = item.parImpedSegId;
        int startLoadId = item.startLoadId;   //2
 ...........
横竖看起来都是人畜无害的一段代码，SearchItem是含有三个int变量的类，searchQueue是存储SearchItem元素的搜索队列，//1处push的元素在while语句中会被取出，其三个变量必然是

item.impedSegId == tree.rootImpedSegId; 
item.parImpedSegId == -1;
item.startLoadId == 0;
可是这里却出现了存储错误，检查的结果是startLoadId值为-1163005939！deque的push_back函数里肯定发生了什么问题，才导致startLoadId从0变成了-1163005939。Debug进入push_back的定义，如下：

      void
      push_back(const value_type& __x)
      {
	if (this->_M_impl._M_finish._M_cur != this->_M_impl._M_finish._M_last - 1)
	  {
	    std::_Construct(this->_M_impl._M_finish._M_cur, __x);
	    ++this->_M_impl._M_finish._M_cur;
	  }
	else
	  _M_push_back_aux(__x);
      }
由于deque的默认构造函数分配了一些存储空间，因此_M_cur还没到末尾，if判断为真，程序执行到++this->_M_impl._M_finish._M_cur;时出现了意想不到的情况。这里为了了解++this->_M_impl._M_finish._M_cur;做了什么，将相关的定义罗列如下：

  template<typename _Tp, typename _Alloc = allocator<_Tp> >
    class deque : protected _Deque_base<_Tp, _Alloc>

  template<typename _Tp, typename _Alloc>
    class _Deque_base
    {
       ....
typedef _Deque_iterator<_Tp,_Tp&,_Tp*>             iterator;
      struct _Deque_impl
	: public _Alloc {
     .........
	iterator _M_finish;
      ..........
      };
       _Deque_impl _M_impl;
    };

  template<typename _Tp, typename _Ref, typename _Ptr>
    struct _Deque_iterator
    {
    .........
      _Tp* _M_cur;
    .........
     }
可以看出deque<SearchItem>中的this->_M_impl._M_finish._M_cur的类型是SearchItem*，由于SearchItem是12字节的，因此想必++this->_M_impl._M_finish._M_cur会将指针移动12个字节。实际结果却是：

---引用---
Before++: this->_M_impl._M_finish._M_cur   = 0x700f38
After++: this->_M_impl._M_finish._M_cur   = 0x700f40
---结束引用---
只增加了8字节！在程序里将SearchItem的大小输出看看，发现确实是12字节：

cerr << sizeof(SearchItem) //结果是12编译器居然口是心非！想了半天突然觉察到还有另外一个文件中的算法也定义了相同名字的类，找到其定义如下：

struct SearchItem
{
    SearchItem (int searchNodeUid, int parentBranchId)
        : nodeUid(searchNodeUid), parBranchId(parentBranchId)
    {}

    int nodeUid;
    int parBranchId;
};
这个是8字节的结构，正好和++操作的结果相符。到这里才恍然大悟，C++的编译模式规定一个类如果不特别指明，它的名字作用域默认是全局的，如果在多个文件中定义了该类，则必须保证类定义完全相同。Devc++居然对两个类定义不做任何检查就用上了，编译器执行指针操作时按照8字节的SearchItem工作，导致startLoadId根本没有被存储到deque中，sizeof操作符却用了12字节的SearchItem！解决的方法很简单，将两个SearchItem加入无名名字空间，冲突就解决了。
Expert C Progamming中将C语言默认的函数名字全局可见这一Language Feature归类为Sin of Commission，也就是C语言不应该做的却做了的事情。C++为了保持兼容性，变本加厉的加入了数量巨大的其他全局外联类型。因此对于确定只用在某个编译单元中的函数，类，类成员函数和产生全局名字的无论其他什么东西，最好用static或者无名名字空间让它们安静的躺在自己的角落里，免得碰上devc++（或者说gcc）这种哑巴编译器搅浑水。
]]></description>
			<content:encoded><![CDATA[<div><blockquote>标题这句话是维护编程语言尊严的常用语，但有时候Language Feature比Bug还要可怕，今天鄙人就被C/C++的一个Language Feature和devc++耍了一把。</blockquote><blockquote>首先来看看这段代码：</blockquote><div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">C++ 代码:</div>
	<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:640px; height:372px; overflow:auto"><div dir="ltr" style="text-align:left;"><div class="c"><ol><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333;">struct</span> SearchItem</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; SearchItem<span style="color: #66cc66;">&#40;</span><span style="color: #993333;">int</span> impedanceSegId, <span style="color: #993333;">int</span> parentImpedSegId, <span style="color: #993333;">int</span> startingLoadId<span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; : impedSegId<span style="color: #66cc66;">&#40;</span>impedanceSegId<span style="color: #66cc66;">&#41;</span>, parImpedSegId<span style="color: #66cc66;">&#40;</span>parentImpedSegId<span style="color: #66cc66;">&#41;</span>, startLoadId<span style="color: #66cc66;">&#40;</span>startingLoadId<span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span>&nbsp; <span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #993333;">int</span> impedSegId, parImpedSegId, startLoadId;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333;">void</span> GetAccImpedAndMtrxStruct<span style="color: #66cc66;">&#40;</span>....<span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; deque&lt;SearchItem&gt; searchQueue;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp;searchQueue.<span style="color: #202020;">push_back</span><span style="color: #66cc66;">&#40;</span>SearchItem<span style="color: #66cc66;">&#40;</span>tree.<span style="color: #202020;">rootImpedSegId</span>, -<span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;&nbsp; <span style="color: #808080; font-style: italic;">//1</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #b1b100;">while</span> <span style="color: #66cc66;">&#40;</span>!searchQueue.<span style="color: #202020;">empty</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; SearchItem&amp; item = searchQueue.<span style="color: #202020;">front</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333;">int</span> impedSegId = item.<span style="color: #202020;">impedSegId</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333;">int</span> parImpedSegId = item.<span style="color: #202020;">parImpedSegId</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333;">int</span> startLoadId = item.<span style="color: #202020;">startLoadId</span>;&nbsp; &nbsp;<span style="color: #808080; font-style: italic;">//2</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;........... </div></li></ol></div></div></pre>
</div><blockquote>横竖看起来都是人畜无害的一段代码，SearchItem是含有三个int变量的类，searchQueue是存储SearchItem元素的搜索队列，//1处push的元素在while语句中会被取出，其三个变量必然是</blockquote><div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">C++ 代码:</div>
	<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:640px; height:84px; overflow:auto"><div dir="ltr" style="text-align:left;"><div class="c"><ol><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">item.<span style="color: #202020;">impedSegId</span> == tree.<span style="color: #202020;">rootImpedSegId</span>; </div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">item.<span style="color: #202020;">parImpedSegId</span> == -<span style="color: #cc66cc;">1</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">item.<span style="color: #202020;">startLoadId</span> == <span style="color: #cc66cc;">0</span>; </div></li></ol></div></div></pre>
</div><blockquote>可是这里却出现了存储错误，检查的结果是startLoadId值为-1163005939！deque的push_back函数里肯定发生了什么问题，才导致startLoadId从0变成了-1163005939。Debug进入push_back的定义，如下：</blockquote><div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">C++ 代码:</div>
	<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:640px; height:212px; overflow:auto"><div dir="ltr" style="text-align:left;"><div class="c"><ol><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333;">void</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; push_back<span style="color: #66cc66;">&#40;</span><span style="color: #993333;">const</span> value_type&amp; __x<span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>this-&gt;_M_impl._M_finish._M_cur != this-&gt;_M_impl._M_finish._M_last - <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;&nbsp; &nbsp;<span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;&nbsp; &nbsp; &nbsp;std::_Construct<span style="color: #66cc66;">&#40;</span>this-&gt;_M_impl._M_finish._M_cur, __x<span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;&nbsp; &nbsp; &nbsp;++this-&gt;_M_impl._M_finish._M_cur;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;&nbsp; &nbsp;<span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #b1b100;">else</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;&nbsp; &nbsp;_M_push_back_aux<span style="color: #66cc66;">&#40;</span>__x<span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span> </div></li></ol></div></div></pre>
</div><blockquote>由于deque的默认构造函数分配了一些存储空间，因此_M_cur还没到末尾，if判断为真，程序执行到++this-&gt;_M_impl._M_finish._M_cur;时出现了意想不到的情况。这里为了了解++this-&gt;_M_impl._M_finish._M_cur;做了什么，将相关的定义罗列如下：</blockquote><div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">C++ 代码:</div>
	<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:640px; height:420px; overflow:auto"><div dir="ltr" style="text-align:left;"><div class="c"><ol><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">template&lt;typename _Tp, typename _Alloc = allocator&lt;_Tp&gt; &gt;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; class deque : protected _Deque_base&lt;_Tp, _Alloc&gt;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; template&lt;typename _Tp, typename _Alloc&gt;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; class _Deque_base</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp;....</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333;">typedef</span> _Deque_iterator&lt;_Tp,_Tp&amp;,_Tp*&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;iterator;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; <span style="color: #993333;">struct</span> _Deque_impl</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; : public _Alloc <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp;.........</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #202020;">iterator</span> _M_finish;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; ..........</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp;_Deque_impl _M_impl;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; template&lt;typename _Tp, typename _Ref, typename _Ptr&gt;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #993333;">struct</span> _Deque_iterator</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; .........</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; _Tp* _M_cur;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; .........</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#125;</span> </div></li></ol></div></div></pre>
</div><blockquote>可以看出deque&lt;SearchItem&gt;中的this-&gt;_M_impl._M_finish._M_cur的类型是SearchItem*，由于SearchItem是12字节的，因此想必++this-&gt;_M_impl._M_finish._M_cur会将指针移动12个字节。实际结果却是：</blockquote><div style="margin:20px; margin-top:5px; ">
	<div class="smallfont" style="margin-bottom:2px">引用:</div>
	<table cellpadding="6" cellspacing="0" border="0" width="100%">
	<tr>
		<td class="alt2" style="border:1px inset">
			
				Before++: this-&gt;_M_impl._M_finish._M_cur   = 0x700f38<br />
After++: this-&gt;_M_impl._M_finish._M_cur   = 0x700f40
			
		</td>
	</tr>
	</table>
</div><blockquote>只增加了8字节！在程序里将SearchItem的大小输出看看，发现确实是12字节：</blockquote><div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">C++ 代码:</div>
	<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:640px; height:52px; overflow:auto"><div dir="ltr" style="text-align:left;"><div class="c"><ol><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">cerr &lt;&lt; <span style="color: #993333;">sizeof</span><span style="color: #66cc66;">&#40;</span>SearchItem<span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">//结果是12 </span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li></ol></div></div></pre>
</div><blockquote>编译器居然口是心非！想了半天突然觉察到还有另外一个文件中的算法也定义了相同名字的类，找到其定义如下：</blockquote><div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">C++ 代码:</div>
	<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:640px; height:180px; overflow:auto"><div dir="ltr" style="text-align:left;"><div class="c"><ol><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333;">struct</span> SearchItem</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; SearchItem <span style="color: #66cc66;">&#40;</span><span style="color: #993333;">int</span> searchNodeUid, <span style="color: #993333;">int</span> parentBranchId<span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; : nodeUid<span style="color: #66cc66;">&#40;</span>searchNodeUid<span style="color: #66cc66;">&#41;</span>, parBranchId<span style="color: #66cc66;">&#40;</span>parentBranchId<span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #993333;">int</span> nodeUid;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #993333;">int</span> parBranchId;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span>; </div></li></ol></div></div></pre>
</div><blockquote>这个是8字节的结构，正好和++操作的结果相符。到这里才恍然大悟，C++的编译模式规定一个类如果不特别指明，它的名字作用域默认是全局的，如果在多个文件中定义了该类，则必须保证类定义完全相同。Devc++居然对两个类定义不做任何检查就用上了，编译器执行指针操作时按照8字节的SearchItem工作，导致startLoadId根本没有被存储到deque中，sizeof操作符却用了12字节的SearchItem！解决的方法很简单，将两个SearchItem加入无名名字空间，冲突就解决了。</blockquote><blockquote>Expert C Progamming中将C语言默认的函数名字全局可见这一Language Feature归类为Sin of Commission，也就是C语言不应该做的却做了的事情。C++为了保持兼容性，变本加厉的加入了数量巨大的其他全局外联类型。因此对于确定只用在某个编译单元中的函数，类，类成员函数和产生全局名字的无论其他什么东西，最好用static或者无名名字空间让它们安静的躺在自己的角落里，免得碰上devc++（或者说gcc）这种哑巴编译器搅浑水。</blockquote></div>

]]></content:encoded>
			<dc:creator>bankrock</dc:creator>
			<guid isPermaLink="true">http://www.cpper.com/c/http://www.cpper.com/bankrock/130.html</guid>
		</item>
		<item>
			<title>__mt_alloc源码分析（1）</title>
			<link>http://www.cpper.com/wqqafnd/129.html</link>
			<pubDate>Tue, 22 Jul 2008 08:24:12 GMT</pubDate>
			<description>http://groups.google.com/group/dl-coder/web/mt-alloc1</description>
			<content:encoded><![CDATA[<div><a rel="nofollow" href="http://groups.google.com/group/dl-coder/web/mt-alloc1" target="_blank">http://groups.google.com/group/dl-coder/web/mt-alloc1</a></div>

]]></content:encoded>
			<dc:creator>wqqafnd</dc:creator>
			<guid isPermaLink="true">http://www.cpper.com/c/http://www.cpper.com/wqqafnd/129.html</guid>
		</item>
		<item>
			<title>hello world</title>
			<link>http://www.cpper.com/gykgod/128.html</link>
			<pubDate>Tue, 15 Jul 2008 12:55:42 GMT</pubDate>
			<description>总算找到一个纯粹点的地方学习C++了，先踩一脚^_^</description>
			<content:encoded><![CDATA[<div>总算找到一个纯粹点的地方学习C++了，先踩一脚^_^</div>

]]></content:encoded>
			<dc:creator>gykgod</dc:creator>
			<guid isPermaLink="true">http://www.cpper.com/c/http://www.cpper.com/gykgod/128.html</guid>
		</item>
		<item>
			<title>2-CNF-SAT问题图形解法的C++实现</title>
			<link>http://www.cpper.com/bankrock/127.html</link>
			<pubDate>Tue, 15 Jul 2008 06:40:51 GMT</pubDate>
			<description><![CDATA[2-CNF-SAT问题图形解法的C++实现
  CNF(conjunctive normal form)是指由多个子句(clause)通过AND关系连接组成的布尔公式，每个子句由若干个文字(literal)通过OR关系连接而成，每个literal可能是一个布尔变量或者布尔变量取反。2-CNF中每个clause含有2个或两个以下的literal，而2-CNF-SAT(2-conjunctive normal form satisfiability)问题就是找出一个2-CNF公式是否有对布尔变量赋值的方法使2-CNF公式的最终结果为1。例如：
               
---引用---
 (x1 OR !x2) AND (x1 OR x2) （这里!表示NOT）
---结束引用---
  就是一个2-CNF公式，如果取x1 = 1, x2 = 0，它的值为(1 OR 1) AND (1 OR 0) = 1，因此这是一个可以满足2-CNF的变量赋值，这个公式属于2-CNF-SAT集。这里介绍一种图形算法解决2-CNF-SAT问题的方法以及C++实现。
  
  一.2-CNF-SAT图形算法以及证明
  3-CNF-SAT问题是NP-Complete的，也就是不大可能出现多项式时间复杂度的解法。但是2-CNF问题却是多项式可解的。下面的解法将2-CNF-SAT问题转化为求解一个图的强连通区域是否符合一定性质，从而判断2-CNF公式是否有解，如果解存在的话还将给出一个可行解。
  2-CNF中一个含有两个literal的clause(l1 OR l2)与(!l1 -> l2)是等价的（这里->是指IF-THEN关系），两式中l1、l2以及结果值value都符合以下的真值表：

---引用---
+-----+-----+-----+
|l1   |l2   |value|
+-----+-----+-----+
|1    |1    |1    |
+-----+-----+-----+
|1    |0    |1    |
+-----+-----+-----+
|0    |1    |1    |
+-----+-----+-----+
|0    |0    |0    |
+-----+-----+-----+
---结束引用---
  因此一个clause可以用IF-THEN关系代替，其他clause中可能出现!l1或者!l2，它们的关系也必须有所表示，这可以通过对上述IF-THEN关系取逆反得到。也就是：
			
---引用---
(l1 OR l2) <==> (!l1 -> l2),(!l2 -> l1)
---结束引用---
  现在开始将2-CNF转化为一个有向图。对于每个变量x建立对应literal x和!x的端点，将clause得出的每个IF-THEN关系转化为图中端点间的一条边，这里称这个有向图为G。可以看出，当2-CNF有满足结果为1的解时，它的所有clause的值都需要为1，因此由clause得出的IF-THEN关系也必须成立，也就是对于G中的每一条边，起始点和终点的literal值需要符合IF-THEN关系；同时，如果G中所有边的起始点和终点的literal值符合IF-THEN关系，并且它们推导出的变量值不相互冲突（例如x1和!x1不会都赋值为0，或者1)，那么这个变量赋值是一个满足2-CNF公式的可行解。
  接下来就需要找到是否存在满足图G中的边所代表的IF-THEN关系的赋值方法。方法如下：搜索图G的所有强连通区域，如果将强连通区域收缩为一个点，则和连接这些强连通点之间边将形成一个无环有向图G'。
  1.如果某个强连通区域中有互为非的literal存在，则不可能存在符合这些边所代表的IF-THEN关系，2-CNF无解。这是因为此时强连通区域内必定有1和0同时存在，由于IF-THEN关系具有传递性，如果存在1则整个强连通区域所有的literal值都需为1才能满足IF-THEN关系。因此这些IF-THEN关系无法满足。同时可以得出一个强连通区域内要么所有Literal的值都为1，要么都为0。
  2.如果没有强连通区域包含互非的literal，那么根据无环有向图G'的拓扑排序关系，可以确定任意两个互非的literal l和!l间的先后关系，将在前的literal值置0，在后的literal置1，可以得出符合IF-THEN关系并且变量赋值不相互冲突的一个2-CNF解。由于0和1互非，明显literal对应的变量值不会相互冲突。因此只需证明这个赋值方法符合IF-THEN关系，证明分为两部分，一为强连通区域内的关系，二为强连通区域之间的关系：
  （1）上面说过满足强连通区域内关系只可能有两种情况，literal都为1或者都为0。现假设使用的赋值方法使得某个强连通区域内出现了两个不同值的literal，l1 = 1、l2 = 0，那么在拓扑排序之前的某个强连通区域F中有!l1 = 0，之后的某个强连通区域B内有!l2 = 1。由于我们构造图G的方法决定如果有边(l1,l2)，那么必然有边(!l2,!l1)，因此由l1到l2有通路可以得出!l2到!l1有通路，得出拓扑排序中B在F之前的矛盾结论，因此强连通区域不可能有不同值的Literal。
  （2）强连通区域间违反IF-THEN关系的情况如下：区域A到B是有通路的，但是区域A值为1而区域B为0，用反证法可以证明这种情况在采用指定的赋值方法时是不可能出现的。假设存在这么两个强连通区域A,B，且literal a属于A，literal b属于B，那么!a所属的强连通区域C值为0在A之前，!b所属的强连通区域D值为1在B之后，且由于a可以到达b，!b也可以到达!a，那么存在D>C>A>B>D的循环拓扑排序关系，这说明强连通区域间不可能出现违反IF-THEN关系的情况。
  至此我们已经证明了该算法可以有效性，而且根据这个算法可以构造出可行的2-CNF解。至于形成强连通区域的算法可以在O(V+E)的时间内完成，因此整个算法是多项式时间复杂度的。
  
  二.2-CNF-SAT算法的C++实现
  实现该算法的关键之处在于如何寻找G的强连通区域，以及检查是否有两个互非的literal存在于同一个强连通区域中。寻找强连通区域的算法由以下几个步骤组成：
  1. 对G进行深度优先搜索，记录下每个节点u搜索完毕的时间f[u]。
  2. 对G的节点按照搜索完毕时间f由大到小排序，并形成G的转置图Gt（转置图是由G的所有边方向都调转形成的）。
  3. 对Gt按排序好节点顺序进行深度优先搜索，此时每次搜索到的点组成的集合就为一个强连通区域。在搜索过程中可以检查是否有互非的literal出现在同一个强连通区域中。
  简单解释一下：这个算法第2步的作用相当于为G的强连通区域进行拓扑排序，由于G和Gt的强连通区域相同，第3步按照拓扑排序搜索Gt时，每次搜索得到一个强连通区域，而不会搜索到其他区域（由于Gt所有的边已经反转，按照拓扑排序关系，如果搜索到其他区域，那么必定是已经搜索过的）。具体的证明请看算法导论关于强连通区域的章节。
  表示2-CNF的类如下：

  struct Literal
{
    Literal() : pSmbl(0) {}

    Literal(Symbol* pSymbol, bool isNotSymbol)
        : pSmbl(pSymbol), isNotSmbl(isNotSymbol)
    {}

    bool Value() const
    { return isNotSmbl ? !pSmbl->value : pSmbl->value; }

    Literal operator!() const
    { return Literal(pSmbl, !isNotSmbl); }


    Symbol* pSmbl;
    bool isNotSmbl;

friend bool FindSCCAndCheckSatisfiability(LtrlGraph& transGraph, std::vector<StrCnnCmpnt>& sccs);
private:
    bool SetSymbolValue(StrCnnCmpnt *pSCC);
};

////////////////////////////////////
struct Clause
{
    Clause(Literal const& literal1, Literal const& literal2, size_t numDummyLiterals)
        : numDummyLtrl(numDummyLiterals)
    {
        ltrls[0] = literal1;
        ltrls[1] = literal2;
    }
    Literal ltrls[2];
    size_t numDummyLtrl;
};

struct TwoCNF
{
    std::vector<Clause> clauses;
    std::set<Symbol> symbols;
    std::vector<Symbol*> dummySmbls;
};
  其中TwoCNF中的dummySmbls指的是当clause中的literal数目小于2时生成的伪布尔变量。例如 l == (l OR RANDOM_SYMBOL) AND (l OR !RANDOM_SYMBOL)，这里的RANDOM_SYMBOL就是一个伪布尔变量。
  表示由2-CNF生成的图类如下：

  /////////////////////////////////////////
struct Node
{
    Node(Literal const& literal) : state(UNSEARCHED), ltrl(literal), pNewNode(0) {}
    Node(Node const& other) : state(UNSEARCHED), tBgnSrch(other.tBgnSrch),
        tEndSrch(other.tEndSrch), ltrl(other.ltrl), pNewNode(0)
    {}

    enum STATE { SEARCHED, SEARCHING, UNSEARCHED } state;
    size_t tBgnSrch, tEndSrch;
    Literal ltrl;
    std::vector<Node*> cnnNodes;

friend void TransposeAndSortGraph(LtrlGraph& graph, LtrlGraph& transGraph);
private:
    Node *pNewNode; //Used for transposing the graph
};

struct LtrlGraph
{
    std::list<Node> nodes;
};
  上述算法的C++实现分为三部分，第一部分为深度优先搜索算法：

void DepthFirstSearch(LtrlGraph& graph)
{
    InitNodesState(graph);

    stack<Node*> searchNodes;

    size_t time = 0;
    for (list<Node>::iterator itorNode = graph.nodes.begin();
        itorNode != graph.nodes.end(); ++itorNode)
    {
        Node& node = *itorNode;
        if (node.state != Node::UNSEARCHED)
            continue;

        searchNodes.push(&node);
        while (!searchNodes.empty())
        {
            Node& node = *searchNodes.top();
            if (node.state == Node::UNSEARCHED)
            {
                node.state = Node::SEARCHING;
                node.tBgnSrch = ++time;
                for (vector<Node*>::iterator itorCnnNode = node.cnnNodes.begin();
                    itorCnnNode != node.cnnNodes.end(); ++itorCnnNode)
                {
                    Node *pCnnNode = *itorCnnNode;
                    if (pCnnNode->state == Node::UNSEARCHED)
                        searchNodes.push(pCnnNode);
                }
            }
            else if (node.state == Node::SEARCHING)
            {
                node.state = Node::SEARCHED;
                node.tEndSrch = ++time;
                searchNodes.pop();
            }
            else
            {
                //The node has already been searched, just pop it from the stack
                searchNodes.pop();
            }
        }
    }
}
  这里使用栈searchNodes记录了搜索节点的顺序，以避免递归调用。searchNodes中的点如果未搜索，则将它标记为正搜索状态，然后搜寻所有相邻的未搜索点将其加入searchNodes中；如果该点的状态为正在搜索，那么说明它的所有子节点都已经搜索完毕，记录下搜索完毕时间并退栈；如果是以搜索状态，说明已经被纳入其他节点的搜索范围，直接退栈。这一步完成后我们得到了所有节点的搜索完毕时间。
  接下来需要生成转置图Gt，并且按照搜索完毕时间排序节点。算法如下：

  struct SortingNode
{
    SortingNode(size_t endSearchTime, Node *pOrgNode)
        : tEndSrch(endSearchTime), pNode(pOrgNode)
    {}

    size_t tEndSrch;
    Node *pNode;
};

inline bool GreaterEndSearchTime(SortingNode const& n1, SortingNode const& n2)
{
    return n1.tEndSrch > n2.tEndSrch;
}

void TransposeAndSortGraph(LtrlGraph& graph, LtrlGraph& transGraph)
{
    //Sort nodes by their end search time
    vector<SortingNode> sortingNodes;
    for (list<Node>::iterator itorNode = graph.nodes.begin();
        itorNode != graph.nodes.end(); ++itorNode)
    {
        Node& node = *itorNode;
        sortingNodes.push_back(SortingNode(node.tEndSrch, &node));
    }
    sort(sortingNodes.begin(), sortingNodes.end(), &GreaterEndSearchTime);

    //Add new nodes in the transposed graph
    for (vector<SortingNode>::iterator itorSN = sortingNodes.begin();
        itorSN != sortingNodes.end(); ++itorSN)
    {
        transGraph.nodes.push_back(*(itorSN->pNode));
        itorSN->pNode->pNewNode = &transGraph.nodes.back();
    }

    //Transpose the graph
    for (list<Node>::iterator itorNode = graph.nodes.begin();
        itorNode != graph.nodes.end(); ++itorNode)
    {
        Node& node = *itorNode;
        for (vector<Node*>::iterator itorCnnNode = node.cnnNodes.begin();
            itorCnnNode != node.cnnNodes.end(); ++itorCnnNode)
        {
            Node* pCnnNode = *itorCnnNode;
            pCnnNode->pNewNode->cnnNodes.push_back(node.pNewNode);
        }
    }
}
  这里先使用了一个辅助排序的结构SortingNode按搜索完毕时间排序节点，然后对原图每个节点和连接节点形成的边，反转连接节点对该节点的边。
  最后一步需要搜索强连通区域以及对变量赋值，同时检查是否有互非的两个literal在同一个强连通区域中。

//Strongly Connected Component
struct StrCnnCmpnt
{
    size_t rank;
    std::vector<Literal> literals;
};
  
bool FindSCCAndCheckSatisfiability(LtrlGraph& transGraph, vector<StrCnnCmpnt>& sccs)
{
    stack<Node*> searchNodes;
    size_t strCnnCmptRank = 0;  //Lower number means higher rank
    for (list<Node>::iterator itorNode = transGraph.nodes.begin();
        itorNode != transGraph.nodes.end(); ++itorNode)
    {
        Node& node = *itorNode;
        if (node.state != Node::UNSEARCHED)
            continue;

        //Create a strong connected component
        sccs.push_back(StrCnnCmpnt());
        StrCnnCmpnt& scc = sccs.back();
        scc.rank = ++strCnnCmptRank;

        searchNodes.push(&node);
        while (!searchNodes.empty())
        {
            Node& node = *searchNodes.top();
            if (node.state == Node::UNSEARCHED)
            {
                node.state = Node::SEARCHING;
                for (vector<Node*>::iterator itorCnnNode = node.cnnNodes.begin();
                    itorCnnNode != node.cnnNodes.end(); ++itorCnnNode)
                {
                    Node *pCnnNode = *itorCnnNode;
                    if (pCnnNode->state == Node::UNSEARCHED)
                        searchNodes.push(pCnnNode);
                }
            }
            else if (node.state == Node::SEARCHING)
            {
                node.state = Node::SEARCHED;
                if (!node.ltrl.SetSymbolValue(&scc))
                //A symbol and its complement is in the same strong connected component,
                //Therefore the symbol value is undefined. No solution is available.
                    return false;
                else
                    scc.literals.push_back(node.ltrl);
                searchNodes.pop();
            }
            else
            {
                searchNodes.pop();
            }
        }
    }
    return true;
}
  这部分算法的主体也是深度优先搜索，但是每个节点搜索完毕后，需要调用node.ltrl.SetSymbolValue(&scc)检查literal所属的强连通区域是否和它互非的literal所属的强连通区域相同，如果相同则2-CNF-SAT无解。Literal类的SetSymbolValue方法如下：

  bool Literal::SetSymbolValue(StrCnnCmpnt *pSCC)
{
    assert(pSCC != 0 && (pSmbl->cntSCC.pSCC == 0 || pSmbl->cntSCC.pNotSCC == 0));

    Symbol::ContainingSCC& cntSCC = pSmbl->cntSCC;
    if (cntSCC.pSCC == 0 && cntSCC.pNotSCC == 0)
    //The first time this symbol is checked
    {
        if (isNotSmbl)
        {
            pSmbl->value = true;
            cntSCC.pNotSCC = pSCC;
        }
        else
        {
            pSmbl->value = false;
            cntSCC.pSCC = pSCC;
        }
        return true;
    }
    else //The second time this symbol is checked
    {
        isNotSmbl ? (cntSCC.pNotSCC = pSCC) : (cntSCC.pSCC = pSCC);
        return cntSCC.IsNotSameSCC();
    }
}
  当该变量第一次被搜索时对其赋值并记录所属的强连通区域，第二次被搜索时检查两个互非Literal所属强连通区域是否相同。
  完整的实现还包括从文件读取2-CNF公式，由TwoCNF类生成图，以及一些输出函数，在这里不罗嗦了，详细看附件里的程序。
  三. 例子
  这里找了几个相对比较简单的例子（其中&表示AND关系，|表示OR关系，!表示NOT）：

  例1.
---引用---
 (x0|x2)&(x0|!x3)&(x1|!x3)&(x1|!x4)&(x2|!x4)&(x5|x0)&(!x5|x1)&(x2|x5)&(x3|x6)&(x4|x6)&(x5|x6)
---结束引用---
  结果：

---引用---
2-CNF: (x0|x2)&(x0|!x3)&(x1|!x3)&(x1|!x4)&(x2|!x4)&(x5|x0)&(!x5|x1)&(x2|x5)&(x3|
x6)&(x4|x6)&(x5|x6)

One Satisfiable Solution:(x0:0) (x1:1) (x2:1) (x3:0) (x4:0) (x5:1) (x6:1)

Graph:
Node x2:
Node !x0: x2 !x3 x5
Node x0:
Node !x2: x0 !x4 x5
Node !x3: x6
Node x3: x0 x1
Node !x1: !x3 !x4 !x5
Node x1:
Node !x4: x6
Node x4: x1 x2
Node !x5: x0 x2 x6
Node x5: x1
Node x6:
Node !x6: x3 x4 x5

Strongly Connected Components:
The SCC of Rank 1 contains the following literals:
!x6
The SCC of Rank 2 contains the following literals:
x4
The SCC of Rank 3 contains the following literals:
!x1
The SCC of Rank 4 contains the following literals:
!x5
The SCC of Rank 5 contains the following literals:
x3
The SCC of Rank 6 contains the following literals:
!x2
The SCC of Rank 7 contains the following literals:
!x4
The SCC of Rank 8 contains the following literals:
x0
The SCC of Rank 9 contains the following literals:
!x0
The SCC of Rank 10 contains the following literals:
!x3
The SCC of Rank 11 contains the following literals:
x6
The SCC of Rank 12 contains the following literals:
x5
The SCC of Rank 13 contains the following literals:
x1
The SCC of Rank 14 contains the following literals:
x2
---结束引用---
  例2.
---引用---
(x1|x2)&(x1|!x2)&(!x1|x2)&(!x1|!x2)&(!x1|x3)&(!x1|!x3)&(x2|!x3)&(x2|x4)&(!x2|x3)&(!x2|!x3)&(x3|x4)&(!x3|!x4)
---结束引用---
  结果：
---引用---
No solution to 2-CNF: (x1|x2)&(x1|!x2)&(!x1|x2)&(!x1|!x2)&(!x1|x3)&(!x1|!x3)&(x2
|!x3)&(x2|x4)&(!x2|x3)&(!x2|!x3)&(x3|x4)&(!x3|!x4)
---结束引用---
]]></description>
			<content:encoded><![CDATA[<div><font size="5">2-CNF-SAT问题图形解法的C++实现</font><br />
  CNF(conjunctive normal form)是指由多个子句(clause)通过AND关系连接组成的布尔公式，每个子句由若干个文字(literal)通过OR关系连接而成，每个literal可能是一个布尔变量或者布尔变量取反。2-CNF中每个clause含有2个或两个以下的literal，而2-CNF-SAT(2-conjunctive normal form satisfiability)问题就是找出一个2-CNF公式是否有对布尔变量赋值的方法使2-CNF公式的最终结果为1。例如：<br />
               <div style="margin:20px; margin-top:5px; ">
	<div class="smallfont" style="margin-bottom:2px">引用:</div>
	<table cellpadding="6" cellspacing="0" border="0" width="100%">
	<tr>
		<td class="alt2" style="border:1px inset">
			
				 (x1 OR !x2) AND (x1 OR x2) （这里!表示NOT）
			
		</td>
	</tr>
	</table>
</div>  就是一个2-CNF公式，如果取x1 = 1, x2 = 0，它的值为(1 OR 1) AND (1 OR 0) = 1，因此这是一个可以满足2-CNF的变量赋值，这个公式属于2-CNF-SAT集。这里介绍一种图形算法解决2-CNF-SAT问题的方法以及C++实现。<br />
  <br />
  一.2-CNF-SAT图形算法以及证明<br />
  3-CNF-SAT问题是NP-Complete的，也就是不大可能出现多项式时间复杂度的解法。但是2-CNF问题却是多项式可解的。下面的解法将2-CNF-SAT问题转化为求解一个图的强连通区域是否符合一定性质，从而判断2-CNF公式是否有解，如果解存在的话还将给出一个可行解。<br />
  2-CNF中一个含有两个literal的clause(l1 OR l2)与(!l1 -&gt; l2)是等价的（这里-&gt;是指IF-THEN关系），两式中l1、l2以及结果值value都符合以下的真值表：<br />
<div style="margin:20px; margin-top:5px; ">
	<div class="smallfont" style="margin-bottom:2px">引用:</div>
	<table cellpadding="6" cellspacing="0" border="0" width="100%">
	<tr>
		<td class="alt2" style="border:1px inset">
			
				+-----+-----+-----+<br />
|l1   |l2   |value|<br />
+-----+-----+-----+<br />
|1    |1    |1    |<br />
+-----+-----+-----+<br />
|1    |0    |1    |<br />
+-----+-----+-----+<br />
|0    |1    |1    |<br />
+-----+-----+-----+<br />
|0    |0    |0    |<br />
+-----+-----+-----+
			
		</td>
	</tr>
	</table>
</div>  因此一个clause可以用IF-THEN关系代替，其他clause中可能出现!l1或者!l2，它们的关系也必须有所表示，这可以通过对上述IF-THEN关系取逆反得到。也就是：<br />
			<div style="margin:20px; margin-top:5px; ">
	<div class="smallfont" style="margin-bottom:2px">引用:</div>
	<table cellpadding="6" cellspacing="0" border="0" width="100%">
	<tr>
		<td class="alt2" style="border:1px inset">
			
				(l1 OR l2) &lt;==&gt; (!l1 -&gt; l2),(!l2 -&gt; l1)
			
		</td>
	</tr>
	</table>
</div>  现在开始将2-CNF转化为一个有向图。对于每个变量x建立对应literal x和!x的端点，将clause得出的每个IF-THEN关系转化为图中端点间的一条边，这里称这个有向图为G。可以看出，当2-CNF有满足结果为1的解时，它的所有clause的值都需要为1，因此由clause得出的IF-THEN关系也必须成立，也就是对于G中的每一条边，起始点和终点的literal值需要符合IF-THEN关系；同时，如果G中所有边的起始点和终点的literal值符合IF-THEN关系，并且它们推导出的变量值不相互冲突（例如x1和!x1不会都赋值为0，或者1)，那么这个变量赋值是一个满足2-CNF公式的可行解。<br />
  接下来就需要找到是否存在满足图G中的边所代表的IF-THEN关系的赋值方法。方法如下：搜索图G的所有强连通区域，如果将强连通区域收缩为一个点，则和连接这些强连通点之间边将形成一个无环有向图G'。<br />
  1.如果某个强连通区域中有互为非的literal存在，则不可能存在符合这些边所代表的IF-THEN关系，2-CNF无解。这是因为此时强连通区域内必定有1和0同时存在，由于IF-THEN关系具有传递性，如果存在1则整个强连通区域所有的literal值都需为1才能满足IF-THEN关系。因此这些IF-THEN关系无法满足。同时可以得出一个强连通区域内要么所有Literal的值都为1，要么都为0。<br />
  2.如果没有强连通区域包含互非的literal，那么根据无环有向图G'的拓扑排序关系，可以确定任意两个互非的literal l和!l间的先后关系，将在前的literal值置0，在后的literal置1，可以得出符合IF-THEN关系并且变量赋值不相互冲突的一个2-CNF解。由于0和1互非，明显literal对应的变量值不会相互冲突。因此只需证明这个赋值方法符合IF-THEN关系，证明分为两部分，一为强连通区域内的关系，二为强连通区域之间的关系：<br />
  （1）上面说过满足强连通区域内关系只可能有两种情况，literal都为1或者都为0。现假设使用的赋值方法使得某个强连通区域内出现了两个不同值的literal，l1 = 1、l2 = 0，那么在拓扑排序之前的某个强连通区域F中有!l1 = 0，之后的某个强连通区域B内有!l2 = 1。由于我们构造图G的方法决定如果有边(l1,l2)，那么必然有边(!l2,!l1)，因此由l1到l2有通路可以得出!l2到!l1有通路，得出拓扑排序中B在F之前的矛盾结论，因此强连通区域不可能有不同值的Literal。<br />
  （2）强连通区域间违反IF-THEN关系的情况如下：区域A到B是有通路的，但是区域A值为1而区域B为0，用反证法可以证明这种情况在采用指定的赋值方法时是不可能出现的。假设存在这么两个强连通区域A,B，且literal a属于A，literal b属于B，那么!a所属的强连通区域C值为0在A之前，!b所属的强连通区域D值为1在B之后，且由于a可以到达b，!b也可以到达!a，那么存在D&gt;C&gt;A&gt;B&gt;D的循环拓扑排序关系，这说明强连通区域间不可能出现违反IF-THEN关系的情况。<br />
  至此我们已经证明了该算法可以有效性，而且根据这个算法可以构造出可行的2-CNF解。至于形成强连通区域的算法可以在O(V+E)的时间内完成，因此整个算法是多项式时间复杂度的。<br />
  <br />
  二.2-CNF-SAT算法的C++实现<br />
  实现该算法的关键之处在于如何寻找G的强连通区域，以及检查是否有两个互非的literal存在于同一个强连通区域中。寻找强连通区域的算法由以下几个步骤组成：<br />
  1. 对G进行深度优先搜索，记录下每个节点u搜索完毕的时间f[u]。<br />
  2. 对G的节点按照搜索完毕时间f由大到小排序，并形成G的转置图Gt（转置图是由G的所有边方向都调转形成的）。<br />
  3. 对Gt按排序好节点顺序进行深度优先搜索，此时每次搜索到的点组成的集合就为一个强连通区域。在搜索过程中可以检查是否有互非的literal出现在同一个强连通区域中。<br />
  简单解释一下：这个算法第2步的作用相当于为G的强连通区域进行拓扑排序，由于G和Gt的强连通区域相同，第3步按照拓扑排序搜索Gt时，每次搜索得到一个强连通区域，而不会搜索到其他区域（由于Gt所有的边已经反转，按照拓扑排序关系，如果搜索到其他区域，那么必定是已经搜索过的）。具体的证明请看算法导论关于强连通区域的章节。<br />
  表示2-CNF的类如下：<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">C++ 代码:</div>
	<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:640px; height:708px; overflow:auto"><div dir="ltr" style="text-align:left;"><div class="c"><ol><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333;">struct</span> Literal</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; Literal<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> : pSmbl<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; Literal<span style="color: #66cc66;">&#40;</span>Symbol* pSymbol, bool isNotSymbol<span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; : pSmbl<span style="color: #66cc66;">&#40;</span>pSymbol<span style="color: #66cc66;">&#41;</span>, isNotSmbl<span style="color: #66cc66;">&#40;</span>isNotSymbol<span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; bool Value<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333;">const</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span> <span style="color: #b1b100;">return</span> isNotSmbl ? !pSmbl-&gt;value : pSmbl-&gt;value; <span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; Literal operator!<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333;">const</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span> <span style="color: #b1b100;">return</span> Literal<span style="color: #66cc66;">&#40;</span>pSmbl, !isNotSmbl<span style="color: #66cc66;">&#41;</span>; <span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; Symbol* pSmbl;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; bool isNotSmbl;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">friend bool FindSCCAndCheckSatisfiability<span style="color: #66cc66;">&#40;</span>LtrlGraph&amp; transGraph, std::<span style="color: #202020;">vector</span>&lt;StrCnnCmpnt&gt;&amp; sccs<span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">private:</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; bool SetSymbolValue<span style="color: #66cc66;">&#40;</span>StrCnnCmpnt *pSCC<span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #808080; font-style: italic;">////////////////////////////////////</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333;">struct</span> Clause</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; Clause<span style="color: #66cc66;">&#40;</span>Literal const&amp; literal1, Literal const&amp; literal2, size_t numDummyLiterals<span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; : numDummyLtrl<span style="color: #66cc66;">&#40;</span>numDummyLiterals<span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; ltrls&amp;<span style="color: #339933;">#91;0&#93; = literal1;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; ltrls&amp;<span style="color: #339933;">#91;1&#93; = literal2;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; Literal ltrls&amp;<span style="color: #339933;">#91;2&#93;;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; size_t numDummyLtrl;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333;">struct</span> TwoCNF</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; std::<span style="color: #202020;">vector</span>&lt;Clause&gt; clauses;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; std::<span style="color: #202020;">set</span>&lt;Symbol&gt; symbols;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; std::<span style="color: #202020;">vector</span>&lt;Symbol*&gt; dummySmbls;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span>; </div></li></ol></div></div></pre>
</div>  其中TwoCNF中的dummySmbls指的是当clause中的literal数目小于2时生成的伪布尔变量。例如 l == (l OR RANDOM_SYMBOL) AND (l OR !RANDOM_SYMBOL)，这里的RANDOM_SYMBOL就是一个伪布尔变量。<br />
  表示由2-CNF生成的图类如下：<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">C++ 代码:</div>
	<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:640px; height:388px; overflow:auto"><div dir="ltr" style="text-align:left;"><div class="c"><ol><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #808080; font-style: italic;">/////////////////////////////////////////</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333;">struct</span> Node</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; Node<span style="color: #66cc66;">&#40;</span>Literal const&amp; literal<span style="color: #66cc66;">&#41;</span> : state<span style="color: #66cc66;">&#40;</span>UNSEARCHED<span style="color: #66cc66;">&#41;</span>, ltrl<span style="color: #66cc66;">&#40;</span>literal<span style="color: #66cc66;">&#41;</span>, pNewNode<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; Node<span style="color: #66cc66;">&#40;</span>Node const&amp; other<span style="color: #66cc66;">&#41;</span> : state<span style="color: #66cc66;">&#40;</span>UNSEARCHED<span style="color: #66cc66;">&#41;</span>, tBgnSrch<span style="color: #66cc66;">&#40;</span>other.<span style="color: #202020;">tBgnSrch</span><span style="color: #66cc66;">&#41;</span>,</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; tEndSrch<span style="color: #66cc66;">&#40;</span>other.<span style="color: #202020;">tEndSrch</span><span style="color: #66cc66;">&#41;</span>, ltrl<span style="color: #66cc66;">&#40;</span>other.<span style="color: #202020;">ltrl</span><span style="color: #66cc66;">&#41;</span>, pNewNode<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">enum</span> STATE <span style="color: #66cc66;">&#123;</span> SEARCHED, SEARCHING, UNSEARCHED <span style="color: #66cc66;">&#125;</span> state;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; size_t tBgnSrch, tEndSrch;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; Literal ltrl;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; std::<span style="color: #202020;">vector</span>&lt;Node*&gt; cnnNodes;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">friend <span style="color: #993333;">void</span> TransposeAndSortGraph<span style="color: #66cc66;">&#40;</span>LtrlGraph&amp; graph, LtrlGraph&amp; transGraph<span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">private:</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; Node *pNewNode; <span style="color: #808080; font-style: italic;">//Used for transposing the graph</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333;">struct</span> LtrlGraph</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; std::<span style="color: #202020;">list</span>&lt;Node&gt; nodes;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span>; </div></li></ol></div></div></pre>
</div>  上述算法的C++实现分为三部分，第一部分为深度优先搜索算法：<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">C++ 代码:</div>
	<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:640px; height:740px; overflow:auto"><div dir="ltr" style="text-align:left;"><div class="c"><ol><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333;">void</span> DepthFirstSearch<span style="color: #66cc66;">&#40;</span>LtrlGraph&amp; graph<span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; InitNodesState<span style="color: #66cc66;">&#40;</span>graph<span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; stack&lt;Node*&gt; searchNodes;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; size_t time = <span style="color: #cc66cc;">0</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #b1b100;">for</span> <span style="color: #66cc66;">&#40;</span>list&lt;Node&gt;::<span style="color: #202020;">iterator</span> itorNode = graph.<span style="color: #202020;">nodes</span>.<span style="color: #202020;">begin</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; itorNode != graph.<span style="color: #202020;">nodes</span>.<span style="color: #202020;">end</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>; ++itorNode<span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; Node&amp; node = *itorNode;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>node.<span style="color: #202020;">state</span> != Node::<span style="color: #202020;">UNSEARCHED</span><span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">continue</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; searchNodes.<span style="color: #202020;">push</span><span style="color: #66cc66;">&#40;</span>&amp;node<span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">while</span> <span style="color: #66cc66;">&#40;</span>!searchNodes.<span style="color: #202020;">empty</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Node&amp; node = *searchNodes.<span style="color: #202020;">top</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>node.<span style="color: #202020;">state</span> == Node::<span style="color: #202020;">UNSEARCHED</span><span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; node.<span style="color: #202020;">state</span> = Node::<span style="color: #202020;">SEARCHING</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; node.<span style="color: #202020;">tBgnSrch</span> = ++time;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">for</span> <span style="color: #66cc66;">&#40;</span>vector&lt;Node*&gt;::<span style="color: #202020;">iterator</span> itorCnnNode = node.<span style="color: #202020;">cnnNodes</span>.<span style="color: #202020;">begin</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; itorCnnNode != node.<span style="color: #202020;">cnnNodes</span>.<span style="color: #202020;">end</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>; ++itorCnnNode<span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Node *pCnnNode = *itorCnnNode;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>pCnnNode-&gt;state == Node::<span style="color: #202020;">UNSEARCHED</span><span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; searchNodes.<span style="color: #202020;">push</span><span style="color: #66cc66;">&#40;</span>pCnnNode<span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>node.<span style="color: #202020;">state</span> == Node::<span style="color: #202020;">SEARCHING</span><span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; node.<span style="color: #202020;">state</span> = Node::<span style="color: #202020;">SEARCHED</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; node.<span style="color: #202020;">tEndSrch</span> = ++time;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; searchNodes.<span style="color: #202020;">pop</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">else</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//The node has already been searched, just pop it from the stack</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; searchNodes.<span style="color: #202020;">pop</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span> </div></li></ol></div></div></pre>
</div>  这里使用栈searchNodes记录了搜索节点的顺序，以避免递归调用。searchNodes中的点如果未搜索，则将它标记为正搜索状态，然后搜寻所有相邻的未搜索点将其加入searchNodes中；如果该点的状态为正在搜索，那么说明它的所有子节点都已经搜索完毕，记录下搜索完毕时间并退栈；如果是以搜索状态，说明已经被纳入其他节点的搜索范围，直接退栈。这一步完成后我们得到了所有节点的搜索完毕时间。<br />
  接下来需要生成转置图Gt，并且按照搜索完毕时间排序节点。算法如下：<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">C++ 代码:</div>
	<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:640px; height:804px; overflow:auto"><div dir="ltr" style="text-align:left;"><div class="c"><ol><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333;">struct</span> SortingNode</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; SortingNode<span style="color: #66cc66;">&#40;</span>size_t endSearchTime, Node *pOrgNode<span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; : tEndSrch<span style="color: #66cc66;">&#40;</span>endSearchTime<span style="color: #66cc66;">&#41;</span>, pNode<span style="color: #66cc66;">&#40;</span>pOrgNode<span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; size_t tEndSrch;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; Node *pNode;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #000000; font-weight: bold;">inline</span> bool GreaterEndSearchTime<span style="color: #66cc66;">&#40;</span>SortingNode const&amp; n1, SortingNode const&amp; n2<span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #b1b100;">return</span> n1.<span style="color: #202020;">tEndSrch</span> &gt; n2.<span style="color: #202020;">tEndSrch</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333;">void</span> TransposeAndSortGraph<span style="color: #66cc66;">&#40;</span>LtrlGraph&amp; graph, LtrlGraph&amp; transGraph<span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//Sort nodes by their end search time</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; vector&lt;SortingNode&gt; sortingNodes;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #b1b100;">for</span> <span style="color: #66cc66;">&#40;</span>list&lt;Node&gt;::<span style="color: #202020;">iterator</span> itorNode = graph.<span style="color: #202020;">nodes</span>.<span style="color: #202020;">begin</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; itorNode != graph.<span style="color: #202020;">nodes</span>.<span style="color: #202020;">end</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>; ++itorNode<span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; Node&amp; node = *itorNode;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; sortingNodes.<span style="color: #202020;">push_back</span><span style="color: #66cc66;">&#40;</span>SortingNode<span style="color: #66cc66;">&#40;</span>node.<span style="color: #202020;">tEndSrch</span>, &amp;node<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; sort<span style="color: #66cc66;">&#40;</span>sortingNodes.<span style="color: #202020;">begin</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>, sortingNodes.<span style="color: #202020;">end</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>, &amp;GreaterEndSearchTime<span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//Add new nodes in the transposed graph</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #b1b100;">for</span> <span style="color: #66cc66;">&#40;</span>vector&lt;SortingNode&gt;::<span style="color: #202020;">iterator</span> itorSN = sortingNodes.<span style="color: #202020;">begin</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; itorSN != sortingNodes.<span style="color: #202020;">end</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>; ++itorSN<span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; transGraph.<span style="color: #202020;">nodes</span>.<span style="color: #202020;">push_back</span><span style="color: #66cc66;">&#40;</span>*<span style="color: #66cc66;">&#40;</span>itorSN-&gt;pNode<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; itorSN-&gt;pNode-&gt;pNewNode = &amp;transGraph.<span style="color: #202020;">nodes</span>.<span style="color: #202020;">back</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//Transpose the graph</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #b1b100;">for</span> <span style="color: #66cc66;">&#40;</span>list&lt;Node&gt;::<span style="color: #202020;">iterator</span> itorNode = graph.<span style="color: #202020;">nodes</span>.<span style="color: #202020;">begin</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; itorNode != graph.<span style="color: #202020;">nodes</span>.<span style="color: #202020;">end</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>; ++itorNode<span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; Node&amp; node = *itorNode;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">for</span> <span style="color: #66cc66;">&#40;</span>vector&lt;Node*&gt;::<span style="color: #202020;">iterator</span> itorCnnNode = node.<span style="color: #202020;">cnnNodes</span>.<span style="color: #202020;">begin</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; itorCnnNode != node.<span style="color: #202020;">cnnNodes</span>.<span style="color: #202020;">end</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>; ++itorCnnNode<span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Node* pCnnNode = *itorCnnNode;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pCnnNode-&gt;pNewNode-&gt;cnnNodes.<span style="color: #202020;">push_back</span><span style="color: #66cc66;">&#40;</span>node.<span style="color: #202020;">pNewNode</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span> </div></li></ol></div></div></pre>
</div>  这里先使用了一个辅助排序的结构SortingNode按搜索完毕时间排序节点，然后对原图每个节点和连接节点形成的边，反转连接节点对该节点的边。<br />
  最后一步需要搜索强连通区域以及对变量赋值，同时检查是否有互非的两个literal在同一个强连通区域中。<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">C++ 代码:</div>
	<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:640px; height:948px; overflow:auto"><div dir="ltr" style="text-align:left;"><div class="c"><ol><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #808080; font-style: italic;">//Strongly Connected Component</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333;">struct</span> StrCnnCmpnt</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; size_t rank;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; std::<span style="color: #202020;">vector</span>&lt;Literal&gt; literals;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; </div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">bool FindSCCAndCheckSatisfiability<span style="color: #66cc66;">&#40;</span>LtrlGraph&amp; transGraph, vector&lt;StrCnnCmpnt&gt;&amp; sccs<span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; stack&lt;Node*&gt; searchNodes;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; size_t strCnnCmptRank = <span style="color: #cc66cc;">0</span>;&nbsp; <span style="color: #808080; font-style: italic;">//Lower number means higher rank</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #b1b100;">for</span> <span style="color: #66cc66;">&#40;</span>list&lt;Node&gt;::<span style="color: #202020;">iterator</span> itorNode = transGraph.<span style="color: #202020;">nodes</span>.<span style="color: #202020;">begin</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; itorNode != transGraph.<span style="color: #202020;">nodes</span>.<span style="color: #202020;">end</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>; ++itorNode<span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; Node&amp; node = *itorNode;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style=