題目大意
給一張有向圖,再給一顆字典樹,有向圖上的每條邊有乙個非負邊權還有乙個字典樹上的字串,從一條邊到另一條邊的代價是那條邊的邊權和這兩個字串的最長公共字首,問從1到其他點的最短路、
題解一看肯定是乙個最短路問題,現在的關鍵問題是如何把這張圖建出來。
我們可以列舉每個點作為兩條邊的中轉點,然後直接把每條邊看作乙個點,對應的去連邊複雜度肯定不對。
我們發現對於所有點,和它們相連的所有邊的總和是\(o(m)\)的,所以我們考慮對每個點,對它相鄰的所有邊建乙個虛樹。
然後觀察到兩條邊代表的字串的最長公共字首也是它們在字典樹上的\(lca\),所以我們在虛樹上列舉\(lca\),然後再去列舉進來的邊,那麼可以作為連出去的邊在虛樹上的\(dfs\)序是一段或兩段連續的區間,然後再對\(dfs\)序建線段樹優化一下連邊就可以了。
**寫了大半天,自閉了。。
#include#include#include#include#include#include#include#include#include#define mm make_pair
#define p pair#define n 100009
#define ls tr[cnt].l
#define rs tr[cnt].r
using namespace std;
typedef long long ll;
priority_queue>q;
int dfn[n],head[n*30],deep[n],p[20][n],tot,a[n],st[n],top,rbs[n],rot,num,_tag[n],tott,df[n],ddf,size[n],rt1,rt2,n,m,k;
ll dis[n*30];
bool vis[n*30];
vectorvec[n],ed[n],ru[n],chu[n],co1[n],co2[n];
vector::iterator it;
inline ll rd()
while(isdigit(c))
return f?-x:x;
}inline bool cmp(int a,int b)
} }}void dfs(int u)
}inline int getlca(int u,int v)
inline void get_tree()
while(top>1)
link(y,x);
} if(dfn[lca]1)
}int build(int l,int r,int tag)
if(tag)
return cnt;
}int mid=(l+r)>>1;
ls=build(l,mid,tag);rs=build(mid+1,r,tag);
if(!tag)link2(ls,cnt,0),link2(rs,cnt,0);
else link2(cnt,ls,0),link2(cnt,rs,0);
return cnt;
}void upd(int cnt,int l,int r,int l,int r,int tag,int x,int len)
int mid=(l+r)>>1;
if(mid>=l)upd(ls,l,mid,l,r,tag,x,len);
if(mid::iterator it=ed[u].begin();it!=ed[u].end();++it)
}void dfs3(int u)
}inline void unit()
for(int i=1;i<=k;++i)vec[i].clear(); }
int main()
tott=m;
for(int i=1;idfs(1);
for(int i=1;i<=n;++i)
}spfa(1);
for(int i=2;i<=n;++i)
unit();
} return 0;
}
SDOI2017 天才黑客
我們不妨思考一下,兩個串的 lcp 的長度在 trie 樹上是什麼?對應點的 lca 的深度。然後就可以想到把邊看成點,然後把邊與邊之間連邊,點權看成這條邊經過所需要的時間。但是這樣子連邊是 o m 2 的,不夠優秀。我們需要進一步優化。考慮兩個點之間的 lcp 可以用什麼來代替?sa 裡面的 he...
SDOI2017 天才黑客
這題太神了。先模claris 大神的題解。首先我們要將邊轉換為點。如果暴力連邊就會有 m 2 的邊,於是我們考慮優化建圖。難點在於快速得到兩個邊的串的 lcp 也就是 trie 樹上的 lca 我們將一堆點按 dfs 序排序,然後 a 到 b 的 lca 就是排序後 min 這裡的 min 是深度最...
SDOI2017 天才黑客 虛樹 最短路
原諒我寫不出簡單題意 可以看到與 trie 樹上的字母以及 lcp 並沒有關係。以邊作為點,可以寫出乙個非常簡單的最短路 dis i min lbrace dis j dep c i v j u i rbrace 還可以建立 u 0 v 0 1,d 0 1,c 0 0 作為原點 但是惡意卡的話有 m...