hdu_2242
題目大意:求將一張無向圖(n個點,m條邊)移除一條邊分為不連通兩部分,使得兩部分的點權和最接近,若無法分為兩部分,則輸出impossible。
題解:拿到題面還算清晰,就是先tarjan
縮點,因為邊雙連通分量肯定無法移除一條邊使得分為不連通的兩部分(因為是無向圖),然後重新建圖,附好點權,就可以開始愉快地跑dfs
了,然後不斷比較取min
即可。但是wa了將近五發之後(檢查完了筆誤細節),筆者不服了,這個方法肯定是沒有問題的,那麼問題在哪?筆者發現,這題編號竟然是從0~n-1,我真的說不出話,審題不仔細,簡直寫到難過,以為改了能對之後,又wa了一發,筆者靜下來檢查,確保無誤後,又提交了一次,又wa了,於是筆者去hdu該題的discuss
找到了一組樣例,不得不說,wa得心服口服,因為題目輸入可能有重邊,即0 1 , 1 0
,因為是無向圖所以存邊肯定呼叫了兩次_add(u,v)
,所以等於0 1
之間,有了四條邊,如果if (v==pre) then continue
,那麼就會出錯,這個點可以說是很坑人了,只能說是自己疏忽了,但是這個也很好解決,只要多加個flag
判斷就好。其實也就是兩個點的邊雙連通要考慮。(個人覺得兩個點不可能叫邊雙連通,暫且這樣稱作吧,即上文0 1 , 1 0
)
#include #include #include #include #include #include #define mem(a,b) memset((a),(b),sizeof(a))
using namespace std;
const int n = 1e4 + 16;
struct edge
;edge edge[n<<1], edge2[n<<1];
bool vis[n];
int head[n], ecnt;
int head2[n], ecnt2;
int sta[n], dfn[n], low[n], col[n];
int val[n], vv[n], f[n];
int top, dep, sum;
int n, m;
void _add( int u, int v )
void _add2( int u, int v )
void init()
void tarjan( int u, int pr )
if ( !dfn[v] )
else if ( vis[v] )
low[u] = min( low[u], low[v] ); }
if ( low[u] == dfn[u] )
top --; }}
void dfs( int u ) }}
int main()
for ( int i = 0; i < m; i ++ )
for ( int i = 0; i < n; i ++ )
if ( !dfn[i] )
tarjan(i, -1);
if ( sum == 1 )
mem(head2,-1);
ecnt2 = 0;
mem(vv,0);
mem(f,0);
for ( int i = 0; i < n; i ++ )
}mem(vis,0);
dfs(1);
int ans = pow;
for ( int i = 1; i <= sum; i ++ )
ans = min( ans, abs( pow - f[i] - f[i] ) );
// cout << "sum: " << sum << endl;
printf("%d\n", ans);
} return 0;
}
Graph Master 連通分量 B
hdu 4635 題目大意 給出一張dag n個點,m條邊 求出能加的最大邊數,使得該圖無重邊,無自環,非強連通。題解 這題題面很好理解,也沒有什麼很難的點,主要是如何求出最大邊數需要動點腦筋。首先要明確一點強連通圖不一定是完全圖,完全圖一定是強連通圖。因為完全圖定義是任意兩點均有連邊,而強連通僅為...
BFS 連通分量 求連通分量
題目描述 求乙個圖的連通分量 input n 頂點數 100 邊 以0 0作為結束標誌 output 連通分量 強連通圖的連通分量為其本身。如果為非連通圖,則連通分量為該圖的最大連通子圖。分析 建乙個100 100的布林矩陣,b x,y true表示x與y連通。同時還要記錄該點是否被遍歷過 然後遍歷...
點連通分量 邊連通分量 割點和橋 強連通分量
老是搞不清他們的關係,不知道該用那份 今天理了一下,整理一下模板 點連通分量 可以求出點連通分量包含哪些點,那個點屬於那個連通分量 struct edge int pre maxn iscut maxn bccno maxn dfs clock,bcc cnt vectorg maxn bcc ma...