有一次比賽的時候遇到了一道強連通分量+縮點的題,過的人挺多,那個時候還沒有做過強連通的題,只能遺憾放棄。比賽回去,立馬整理了強連通縮點的模板,做了那道題。時隔多日,再找一道強連通的題,來聯絡一下
題目大意:有乙個有向圖,第一問:從幾個點開始走能夠全部遍歷一遍,第二問:如果要把整個有向圖變成強連通至少 需要加幾條邊。
解法:第一問:只需要縮點之後,看入度為0的點有幾個便可,入度為0的點是不能被到達的,只能作為起點,入度不為 0的點一定會被某乙個入度為0的點到達。
第二問:只要找出入度為0的點和出度為0的點的最大值即可,若ru>chu,那麼需要把每乙個入度為0的點都連線 到某乙個連通分量裡。若ru
此外:如果原圖只有乙個強連通分量,那麼直接輸出1,0;
**:
#include #include #include #include #include #define maxn 110
#define inf 1<<29
using namespace std;
int v;
vectorg[maxn]; //圖的鄰接表表示
vectorrg[maxn]; //把邊反向後的圖
vectorvs; //後序遍歷順序的頂點列表
bool used[maxn];
int cmp[maxn],k; //所屬強聯通分量的拓撲系 k表示強聯通分量的個數
void addedge(int from,int to)
void dfs(int v)
vs.push_back(v);
}void rdfs(int v,int k)
}void scc()
memset(used,0,sizeof(used));
k = 0;
for(int i = vs.size() - 1; i >= 0; i--)
}int main()
memset(cmp,0,sizeof(cmp));
for(int i = 1; i <= v; i++)
scc();//求強聯通分量加縮點
/*for(int i = 1; i <= v; i++)
printf("%d ",cmp[i]);*/
int in[maxn],out[maxn]; //計算入度和出度
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
for(int i = 1; i <= v ; i++)
}int ru,chu;
ru = chu = 0;
for(int i = 0; i < k ; i++)
if(k == 1)
else
printf("%d\n%d\n",ru,ru>chu?ru:chu);
}
poj1236 強連通分量 縮點
題意 n 2 題解 找強連通分量,縮點。記f i 為縮完點後的新圖中各點入度,g i 為出度,ans1為f i 0的點的數目,ans2為g i 0的點的數目則第一問為ans1,第二問則為max。至於第二問的解釋,我的想法是對於得到的dag圖,考慮其中的出度為0的點和入度為0的點組成的點集v,將這些點...
poj 1236 強連通分量 縮點
有向無環圖中所有入度不為0的點,一定 可以由某個入度為0的點出發可達。假定有 n 個入度為0的點,m個出度為0的點,max m,n 就是第二個問題的解。include include include include include include include using namespace st...
POJ 1236 強連通分量
題目鏈結 翻譯一下題目吧,大致含義就是,有n個學校,現在要向n個學校傳遞乙個軟體,如果a學校願意支援b學校,那麼給了a,a就會給b,但是a支援b但是b不一定支援a 有向圖警告 要求什麼呢,最少給多少個學校就可以給到全部的學校,最少加幾個支援關係,可以使得給任意乙個學校就可以傳遞到全部學校去。思路 第...