給出乙個無向圖,n<=100000,m <= 300000,判斷圖中是否有奇圈,是否有偶圈。
對於奇圈的判定,可以利用二分圖染色。若此圖是二分圖,那麼其中一定不存在奇圈,若此圖不是二分圖,那必定存在奇圈。若原圖不連通,則對每個連通分量分別做二分圖染色對於偶圈的判定,首先考慮所有圈必然在邊雙連通分量中(題中要求的圈不一定是簡單圈),邊雙連通分量之間是不存在圈的(因為橋的存在)。將原圖用tarjan做邊雙連通分量分解。對於每個邊雙連通分量,其中必然存在至少乙個圈。若此連通分量僅僅是乙個圈,那麼可以直接判斷這個圈的奇偶性。若此連通分量是多個圈的疊加,考慮其中有公共部分的兩個圈a,b,他們的奇偶性只有三種:奇奇,奇偶,偶偶。後兩種已經存在偶圈,不考慮。對於第一種情況,我們一定可以通過取這兩個圈的非公共邊組成乙個更大的偶圈。綜上,若此連通分量是多個圈的疊加,則一定存在偶圈。
也就是說此邊雙連通分量有偶圈,當且僅當此邊雙連通分量是乙個單一的偶圈或者是多個圈的疊加。單一的圈的判定方法:可以先求出邊雙連通分量中的點數a,和邊數b,若a==b則是單一圈,否則是多圈疊加。
在求邊雙連通分量的過程中,tarjan標記橋別忘了反向邊也要標記。
#include
#include
#include
#include
#pragma comment(linker,"/stack:102400000,102400000")
using
namespace
std;
const
int maxn = 2e5;
struct edge;//isb標記橋,rev記錄反向邊
int n,m;
vector
g[maxn];
int color[maxn],dfs_clock,pre[maxn],low[maxn],vis[maxn],iscut[maxn];
void add_edge(int a,int b)
bool bipartite(int u)
else
if(color[v] == color[u])
return
false;
}return
true;
}int dfs(int u,int fa)
}else
if(pre[v] < pre[u] && v!=fa)
lowu = min(lowu,pre[v]);
}if(fa < 0 && child == 1) iscut[u] = 0;
low[u] = lowu;
return lowu;
}int ncnt,mcnt;
void dfs2(int u)
}}int main()
for(int i =1; i <= n; i++)
if(!color[i])
for(int i = 1; i <= n; i++)
if(!pre[i])
dfs(i,-1);
for(int i = 1; i <= n; i++)
if(!vis[i])}}
if(odd)
printf("yes\n");
else
printf("no\n");
if(even)
printf("yes\n");
else
printf("no\n");
}
return
0;}
HDU 5215 Cycle 奇圈和偶圈
題目大意 給你一張有向圖,問是否存在奇圈和偶圈 解題思路 二分圖染色,如果染色成功,證明沒有奇圈 給出大神的傳送門 染色的時候,如果下乙個點已經被染了,說明已經形成了乙個圈了,那怎麼判斷是奇圈還是偶圈 首先,該點如果和下乙個點的顏色不同,那麼該圈就是偶圈了,反之,如果該點與下一點的顏色相同,該圈就是...
雙聯通分量 HDOJ 5215 Cycle
bc的官方題解已經講的不能再清楚了。對於問題1,我們只需要進行二分圖染色判定這個圖是否是二分圖即可 二分圖中必定不存在奇環,而非二分圖中必定存在奇環 對於問題2,首先我們注意到乙個環一定存在於雙聯通分量 既去掉任何一條邊後仍然聯通的點集 內 通過tarjan演算法,可以分離出所有的雙聯通分量,然後分...
hdu1285 hdu4857 拓撲排序
一 原題內容 problem description 有n個比賽隊 1 n 500 編號依次為1,2,3,n進行比賽,比賽結束後,裁判委員會要將所有參賽隊伍從前往後依次排名,但現在裁判委員會不能直接獲得每個隊的比賽成績,只知道每場比賽的結果,即p1贏p2,用p1,p2表示,排名時p1在p2之前。現在...