雖然感覺難度其實並不到黑題的難度
其實這道題並沒用什麼特別的知識,只是tarjan求雙聯通分量和lca的結合。所以,我們可以很顯然的發現(如此惡劣的詞彙,逃
這道題其實就是給你乙個無向圖,其中乙個點雙聯通分量算作乙個點,詢問兩個點之間(包括這兩個點)有多少點(注意重邊不需要縮點)。注意這裡的圖是無向圖,所以我們如果用單純的tarjan求強連通分量,就會得到wa的好成績。
因此 --->我們用tarjan雙聯同分量進行縮點,特判一下如果是他的父親,就不執行(去除重邊的影響),然後\(o(m)\)重建圖,跑一邊lca求距離就好了
這裡有坑:
1.沒有關注重邊。2.查詢寫成原圖中的編號,應為所在聯通塊的編號。
3.資料略卡常,要用快讀進行輸入。
#include#include#include#include#includeusing namespace std;
#define n 10010
#define m 100010
int head[n],dfn[n],low[n];
int idx,link[n],tot1,fa[n][25];
int belong[n],m,n,tot2;
int depth[n],xx[m],yy[m];
bool vis[n];
stackst;
struct edgee[m*2],edge[m*2];
inline int read()
while(ch >= '0' && ch <= '9')
return s * w;
}inline void add_edge(int u,int v)
int cnt;
void tarjan(int u,int from) else if(vis[v])
low[u] = min(low[u],dfn[v]);
}if(dfn[u] == low[u])
}}inline void add_edge2(int u,int v)
void dfs(int u,int from,int deepth)
}int lca(int u,int v)
return fa[u][0];
}int ans[28000];
int print(int n)
if(n < 0)
while(n)
for(int i = cur ; i >= 1 ; i--)
printf("%d",ans[i]);
cout<}int main()
for(int i = 1 ; i <= n ; i++)
if(dfn[i] == -1)
tarjan(i,-1);
for(int i = 1 ; i <= m ; i++)
}dfs(belong[1],belong[1],0);
for(int j = 1 ; j <= 22 ; j++)
for(int i = 1 ; i <= cnt ; i++)
fa[i][j] = fa[fa[i][j - 1]][j - 1];
int t;
t = read();
while(t--)
return 0;
}
洛谷2783 有機化學之神偶爾會做作弊
題目戳這裡 一句話題意 乙個無向圖,先縮掉所有的環,再詢問兩點直接隔了多少個點 兩端也算 solution 似乎難度稱不上黑題,思路也很明顯 直接tarjan縮點後求lca,深度之差就是相隔的點數。但注意特判lca x或y的情況。本來早就可以a了,結果居然lca打錯,無語.可能難就難在 比較長,有點...
luogu P2783 有機化學之神偶爾會做作弊
嘟嘟嘟 一道很水的黑題 邊雙縮點後用lca求樹上兩點間路徑即可。但是比較坑的是這道題是忽略重邊的,結果我還特意考慮了重邊,然後wa了幾發。還有兩個點tle了,原因是建新圖的時候出現了重邊。這個重邊不是演算法的問題,因為邊雙縮點後不可能有重邊,而是寫法上的問題 在建無向邊的時候,習慣addedge x...
洛谷 P1994 有機物燃燒
本來準備弄難點的,還是算了吧 輸入一種有機物,輸出與氧氣反應化學方程式中co2和h2o的係數 輸入格式 一行,乙個字串,表示有機物 輸出格式 兩個數,分別為co2和h2o的係數 輸入樣例 1 複製 c2h5oh 輸出樣例 1 複製 2 3 只含有c h o三種元素 思路 模擬。include inc...