日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

POJ2942 Knights of the Round Table 点双连通分量 二分图判定

發布時間:2025/3/15 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 POJ2942 Knights of the Round Table 点双连通分量 二分图判定 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目大意

有N個騎士,給出某些騎士之間的仇恨關系,每次開會時會選一些騎士開,騎士們會圍坐在一個圓桌旁。一次會議能夠順利舉行,要滿足兩個條件:1.任意相互憎恨的兩個騎士不能相鄰。2.開會人數為大于2的奇數。若某個騎士任何會議都不能參加,那么就必須將他踢出,給出騎士之間的仇恨關系,問最少需要踢出多少個騎士?

總體思路

依題意,把騎士看作節點,每個騎士向其不仇視的騎士連一條無向邊。如果一個騎士所代表的節點在一個奇環內,則該騎士便可以與環內節點所代表的騎士一起開會,所以我們要找到那個奇環。

我們要先找到環,再看看它是不是奇的。

利用的性質

  • 圖中所有的環包含在圖的點雙連通分量中(因為環中不存在割點)(圖的點雙連通分量為圖的極大不存在割點的子圖)。
  • 如果一個雙連通分量中存在奇環,則該雙連通分量中的所有節點都屬于一個奇環(如果存在一個奇環,則該雙連通分量中的其它節點必由兩條路徑與奇環中的兩個節點相連(否則路徑上就有割點了)。兩個節點之間因為在奇環中,所以連接兩節點奇環內必有兩條路徑,一條是奇的,一條是偶的。因為經過那個其它節點與這兩個節點的路徑長度是固定的,所以命題成立)。

求點雙連通分量:Tarjan ——的一種方法

在基本Tarjan算法的基礎上構造一個維護節點的棧,其保證棧內節點cur和cur以上的所有節點都位于一個或多個雙連通分量中。如果cur是割點,使得cur是某個遍歷出的相鄰節點v所屬的雙連通分量中DfsN值最小的節點,則一直將棧內v及以上的所有節點和cur納入一個雙連通分量中,將v及以上所有節點出棧。

注意事項

  • 永遠記住如果cur是割點不代表所有與cur相鄰的節點都屬于不同的雙連通分量!所以是出棧到v,而不是出棧到cur。
  • 即使cur是根節點且cnt<1(其實在此題中cnt根本不需要),也要進行出棧操作,因為此算法是一邊遍歷一邊設雙連通分量,如果根遍歷到的第一個v節點便與根屬于一個雙連通分量,cnt不小于1導致了跳過。
  • 記住判斷割點的依據是cur->DfsN <= v->Low,而不是cur->DfsN <= cur->Low。
  • 根節點可能不是割點,但是根節點必須在一個點雙連通分量中,所以要注意Dfs完后的出棧操作。

判斷奇環——二分圖判定

利用染色的方法,將節點分為黑白兩種顏色,一個節點要嘗試將下一個節點染成與自己不同的顏色。如果下一個節點已有與自己相同的顏色,則此非二分圖,存在奇環。如果最終得到了一個二分圖,則不存在奇環。

?

AC待優化代碼:

#include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std;#define LOOP(i,n) for(int i=1; i<=n; i++) const int MAX_NODE = 5000, MAX_EDGE = 1000010 * 2;struct Node; struct Edge;struct Node {int Id, DfsN, Low, Color;bool InBlock, InTable;//inTable:能加入圓桌會議Edge *Head; }_nodes[MAX_NODE];struct Edge {Node *From, *To;Edge *Next, *Rev;Edge(){}Edge(Node *from, Node *to, Edge *next):From(from),To(to),Next(next){} }*_edges[MAX_EDGE];int _vCount, _eCount, DfsCnt; vector<vector<Node*>> Blocks; vector<Node*> Stack;void Init(int n) {memset(_nodes, 0, sizeof(_nodes));_eCount = DfsCnt = 0;Blocks.clear();Stack.clear();_vCount = n; }Edge *NewEdge(Node *from, Node *to, Edge *next) {_eCount++;if (_edges[_eCount])*_edges[_eCount] = Edge(from, to, next);else_edges[_eCount] = new Edge(from, to, next);return _edges[_eCount]; }Edge *AddEdge(Node *from, Node *to) {Edge *e = NewEdge(from, to, from->Head);from->Head = e;return e; }void Build(int uId, int vId, bool is2d) {Node *u = uId + _nodes, *v = vId + _nodes;u->Id = uId;v->Id = vId;Edge *e1 = AddEdge(u, v);if (is2d) {Edge *e2 = AddEdge(v, u);e1->Rev = e2;e2->Rev = e1;} }void DeStack(Node *cut, Node *v) {Node *blockMember;vector<Node*> newBlock;Blocks.push_back(newBlock);while(!Stack.empty()) {//易忘點blockMember = Stack.back();Blocks.back().push_back(blockMember);Stack.pop_back();if (blockMember == v)break;};if (cut != NULL)Blocks.back().push_back(cut); }void Dfs(Node *u,Node *root) {u->DfsN = u->Low = ++DfsCnt;Stack.push_back(u);for (Edge *e = u->Head; e; e = e->Next) {if (!e->To->DfsN) {Dfs(e->To,root);u->Low = min(u->Low, e->To->Low);if (u->DfsN <= e->To->Low)DeStack(u, e->To);}elseu->Low = min(u->Low, e->To->DfsN);} }void SetBlock() {for (int i = 1; i <= _vCount; i++) {if (!_nodes[i].DfsN) {Stack.clear();Node *root = i + _nodes;Dfs(root, root);if (!Stack.empty())DeStack(root, NULL);}} }bool HaveOrdCircle(Node *u, int curColor) {u->Color = curColor;for (Edge *e = u->Head; e; e = e->Next) {if (e->To->InBlock) {if (e->To->Color == -1) {if (HaveOrdCircle(e->To, !curColor))return true;}else if (e->To->Color == curColor)return true;}}return false; }void SetTableMember() {int blockCnt = Blocks.size();for (int i = 0; i < blockCnt; i++) {int nodeCnt = Blocks[i].size();if (nodeCnt <= 2)continue;for (int j = 0; j < nodeCnt; j++) {Blocks[i][j]->InBlock = true;Blocks[i][j]->Color = -1;}for (int j = 0; j < nodeCnt; j++)if (HaveOrdCircle(Blocks[i][0], 0))for (int j = 0; j < nodeCnt; j++)Blocks[i][j]->InTable = true;for (int j = 0; j < nodeCnt; j++)Blocks[i][j]->InBlock = false;} }int main() { #ifdef _DEBUGfreopen("c:\\noi\\source\\input.txt", "r", stdin);freopen("c:\\noi\\source\\output.txt", "w", stdout); #endifstatic bool hate[MAX_NODE][MAX_NODE];int totNode, totHate, a, b;while (~scanf("%d%d", &totNode, &totHate) && (totNode || totHate)) {Init(totNode);memset(hate, false, sizeof(hate));for (int i = 1; i <= totHate; i++) {scanf("%d%d", &a, &b);hate[a][b] = hate[b][a] = true;}for (int i = 1; i <= totNode; i++)for (int j = 1; j <= totNode; j++)if (i != j && !hate[i][j])Build(i, j, false);SetBlock();SetTableMember();int cnt = 0;for (int i = 1; i <= _vCount; i++)if (!_nodes[i].InTable)cnt++;printf("%d\n", cnt);}return 0; }

  

?

轉載于:https://www.cnblogs.com/headboy2002/p/8471238.html

總結

以上是生活随笔為你收集整理的POJ2942 Knights of the Round Table 点双连通分量 二分图判定的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日操干| 成人夜夜 | 日本理论片午伦夜理片在线观看 | 国产91在线播放九色 | 四虎色网 | 欧美日韩国产一区二区在线观看 | 深夜福利免费视频 | 无码国产69精品久久久久网站 | 四虎福利 | 成人涩涩网站 | 成年人精品视频 | 国产口爆吞精一区二区 | 午夜日韩福利 | 人人爽夜夜爽 | 国产亚洲系列 | 国产黄色视屏 | 黑人高潮一区二区三区在线看 | 999毛片 | 亚洲色图校园春色 | 91成人国产 | 波多野42部无码喷潮在线 | 亚洲精品影视 | 久久综合综合久久 | 精品视频一区二区三区四区 | 午夜h视频 | 久99久视频 | 中文字幕在线视频一区二区 | 国产另类在线 | 黑人操bb| 国产午夜精品一区二区三区欧美 | 放几个免费的毛片出来看 | 无码熟妇人妻av | 国产清纯白嫩初高中在线观看性色 | 天堂影音 | 视频一区日韩 | 中国人与拘一级毛片 | 体内精视频xxxxx | 国产sm网站| 亚洲天堂高清 | 国产成人精品久久久 | 91在线免费视频观看 | 精品视频久久久久 | 国产又粗又猛又爽又黄的视频在线观看动漫 | 四色成人 | 久久国产精品国产精品 | 亚洲生活片 | 波多野结衣一级 | 亚洲免费精品视频在线观看 | 欧美国产乱视频 | 边啃奶头边躁狠狠躁 | 黄色片久久久久 | 亚洲AV永久无码国产精品国产 | 成人日批 | 一本—道久久a久久精品蜜桃 | 欧美三级日本三级 | 国产一级片毛片 | 婷婷免费 | 欧美一级电影在线 | 成人av免费播放 | 久久99精品波多结衣一区 | 精品久久免费视频 | 欧美做爰猛烈床戏大尺度 | 亚洲永久无码精品 | 色妻影院 | 色亚洲色图 | 不卡av免费在线观看 | 精品国产专区 | 国产精品69久久久久 | www.夜夜爽 | 黑人操亚洲女人 | 性欧美video另类hd尤物 | 亚洲a图 | 亚洲精品视频在线播放 | 色多多网站 | 女女h百合无遮涩涩漫画软件 | 一区=区三区乱码 | 免费黄网站在线观看 | 国产黄色大片在线观看 | 久久影视av | 日韩黄色一级大片 | 国产在线视频一区二区三区 | 久久久久麻豆v国产精华液好用吗 | 亚洲一区二区三区成人 | 黄色片在线播放 | 国产精品www色诱视频 | 综合网激情 | 欧美综合国产 | 蜜桃视频无码区在线观看 | 91青青视频| 色综合免费视频 | 国产精品成人一区二区三区电影毛片 | 日本黄色片免费看 | 国产伦精品一区二区三区 | 日本a级黄 | 国产成人看片 | 国产精品伦理一区 | 97精品一区 | 星空大象mv高清在线观看免费 | 精品视频一区二区三区在线观看 |