傳送門
求嚴格次小生成樹(權值和嚴格小於最小生成樹)
和無限制的次小生成樹一樣,唯一不同的是,嚴格小於,只需要將刪除非樹邊連線的兩點樹鏈上的最長邊改為刪除1.如果最長邊不等於該邊,就直接計算2.如果等於,就用次長邊計算。
在最小生成樹上倍增即可。
#includeusing namespace std;
namespace io
templateinline void wr(t x)
}using namespace io;
const int n = 1e5+5, m = 3e5+5;
const long long oo = 2e18;
long long ans1 = 0, ans2 = oo;
int n, m;
int ecnt, adj[n], nxt[m << 1], go[m << 1], len[m <<1];
int anc[n], dep[n];
int fa[n][25];
long long maxx[n][25];
bool used[m];
struct node
inline void load()
}edge[m];
inline void addedge(int u, int v, int c)
inline int getanc(int x)
inline void dfs(int u, int f, int ee)
for(int e = adj[u]; e; e = nxt[e])
}inline pairget(int u, int v)
else if(maxx[u][i] > ma2)
ma2 = maxx[u][i];
u = fa[u][i];
} }if(u == v) return make_pair(ma1, ma2);
for(int i = 20; i >= 0; i--)
else if(maxx[v][i] > ma2)
ma2 = maxx[v][i];
v = fa[v][i];
//-----------------------------
if(maxx[u][i] > ma1)
else if(maxx[u][i] > ma2)
ma2 = maxx[u][i];
u = fa[u][i];
} }if(maxx[v][0] > ma1)
else if(maxx[v][0] > ma2)
ma2 = maxx[v][0];
//-----------------------------
if(maxx[u][0] > ma1)
else if(maxx[u][0] > ma2)
ma2 = maxx[u][0];
return make_pair(ma1, ma2);
}int main()
} for(int i = 1; i <= n; i++)
for(int j = 0; j <= 25; j++)
maxx[i][j] = oo;
dfs(1, 0, 0);
for(int i = 1; i <= m; i++)
printf("%lld", ans2);
return 0;
}
BZOJ 1977 嚴格次小生成樹
題目鏈結 題意 求乙個圖的嚴格次小生成樹,n 100000,m 300000,邊權非負且 1e9 思路 按照正常次小生成樹思路,先生成一顆最小生成樹,並記錄任意兩點路徑上的最長邊,然後列舉非最小樹邊來求得答案,但現在要求的是嚴格次小生成樹所以我們還得知道兩點路徑上的嚴格次長邊 我們考慮使用lca維護...
BZOJ 1977 次小生成樹(最近公共祖先)
題意 求一棵樹的嚴格次小生成樹,即權值嚴格大於最小生成樹且權值最小的生成樹。思路 若現在已經得到了最小生成樹,那麼若 新增一條邊e,就會得到乙個環,我們只需要去掉環上權值小於e且最大的一條邊就會得到另一棵較優的生成樹。因此,只需要列舉不在生成樹上的邊,計算將其添 加到最小生成樹中得到的新生成樹的權值...
BZOJ 1977 次小生成樹(最近公共祖先)
題意 求一棵樹的嚴格次小生成樹,即權值嚴格大於最小生成樹且權值最小的生成樹。先求最小生成樹,對於每個不在樹中的邊,取兩點間路徑的資訊,如果這條邊的權值等於路徑中的權值最大值,那就刪掉路徑中的次大值,加上這條非樹邊,更新答案 否則刪掉路徑中的最大值,加上這條非樹邊,更新答案。1 include2 in...