有 n(2<=n<=5000) 個人,m(0
需要注意的是 support 是可以傳遞的,比如:a support b && b support c,那麼,c 得到的 support 是 2
可以想到的是,列舉每個人得到的 support 的個數,這個做法是 o(n^2) 的。在 50 組資料的情況下,想要在 2s 內出結果,有點不現實
思來想去,這道題貌似沒有什麼好的做法
那麼就想想怎麼盡可能多的「剪枝」吧
首先,如果一堆人中,每兩個人都可以相互支援(間接或者直接),那麼這一堆人可以縮成乙個「人」。
縮點之後,我們再反向建圖,那麼,能夠得到最多的 support 的那一堆人,一定是圖中入度為 0 的點
對建好的圖中那些入度為 0 的點,dfs 遍歷一遍,得到 support 這個點的人數
找到 support 人數最多的點,輸出組成這些點的人即可
#include #include #include #include #include #include using namespace std;
const int n=5006;
stack s;
vector adj[n], arc[n], com[n], ans;
int n, m, t, ind, t, sum;
int dfn[n], low[n], id[n], in[n];
bool vs[n];
void tarjan(int u)
else if(vs[v] && low[u]>dfn[v]) low[u]=dfn[v];
}if(low[u]==dfn[u])
ind++;
}}void dfs(int u)
{ vs[u]=1;
int len=(int)arc[u].size();
sum+=(int)com[u].size(); // 可以優化
for(int i=0; i
hdu3639 強連通 縮點 tarjan演算法
題意 投票 如果a投給b,b投給c,那麼c也會得到a的投票。現在要求誰的票最多,並輸出這些人的編號。題解 跑tarjan求強連通分量,在強連通分量的隊伍中,每個點都是相互投票的。那麼對原圖進行縮點,然後反向建圖。選出入度為0的隊伍進行dfs,求出有隊伍投給了這個隊伍。將總人數求和減去自己即可。最後輸...
強連通分量 tarjan求強連通分量
雙dfs方法就是正dfs掃一遍,然後將邊反向dfs掃一遍。挑戰程式設計 上有說明。雙dfs 1 include 2 include 3 include 4 include 5 6using namespace std 7const int maxn 1e4 5 8 vector g maxn 圖的鄰...
強連通分量
對於有向圖的乙個頂點集,如果從這個頂點集的任何一點出發都可以到達該頂點集的其餘各個頂點,那麼該頂點集稱為該有向圖的乙個強連通分量。有向連通圖的全部頂點組成乙個強連通分量。我們可以利用tarjan演算法求強連通分量。define n 1000 struct edge e 100000 int ec,p...