最小瓶颈路
Posted cptbtptpbcptbtptp
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最小瓶颈路相关的知识,希望对你有一定的参考价值。
题目链接:最小瓶颈路
首先,这是一道无脑题
话说我上学校正常信息课20分钟打完,然后一遍A了?
首先不难想到,这个最小瓶颈路一定在最小生成树上
然后我们建一下这棵MST,然后DFS找出S到T的权的最大值
我没这样做
发现n<=1000,感到很happy,发现K<=1000,又很happy
然后上一个大暴力的思路:
可以考虑建k次MST,然后建的时候判断Getfa(s)是否等于Getfa(t),期间存最大值;对于-1的情况,可以考虑再建一个并查集维护连通性
所以无脑代码如下(极其好打):
1 #define INF 0x7fffffff 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 typedef long long ll; 8 const int N = 1e3 + 5,M = 1e5 + 5; 9 struct Edge 10 { 11 int x,y,val; 12 }a[M]; 13 int n,m,k,fa[N],Query[N]; 14 bool cmp(Edge p,Edge q) 15 { 16 return p.val<q.val; 17 } 18 inline int read() 19 { 20 int x=0,w=1; char c=getchar(); 21 while (c>‘9‘ || c<‘0‘) {if (c==‘-‘) w=-1; c=getchar();} 22 while (c<=‘9‘ && c>=‘0‘) {x=(x<<1)+(x<<3)+c-‘0‘; c=getchar();} 23 return w*x; 24 } 25 int getfa(int x) 26 { 27 if (x!=fa[x]) fa[x]=getfa(fa[x]); 28 return fa[x]; 29 } 30 int finfa(int x) 31 { 32 if (Query[x]!=x) Query[x]=finfa(Query[x]); 33 return Query[x]; 34 } 35 void Init() 36 { 37 for (int i=1;i<=n;++i) 38 fa[i]=i; 39 } 40 void combine(int x,int y) 41 { 42 int t1,t2; 43 t1=finfa(x); t2=finfa(y); 44 if (t1!=t2) Query[t1]=t2; 45 else return ; 46 } 47 int main() 48 { 49 n=read(); m=read(); k=read(); 50 for (int i=1;i<=n;++i) 51 Query[i]=i; 52 for (int i=1;i<=m;++i) 53 a[i].x=read(),a[i].y=read(),a[i].val=read(),combine(a[i].x,a[i].y); 54 sort(a+1,a+m+1,cmp); 55 while (k--) 56 { 57 int s,t; 58 s=read(); t=read(); 59 if (finfa(s)!=finfa(t)) 60 { 61 printf("-1"); 62 continue; 63 } 64 int ans=-INF; 65 memset(fa,0,sizeof(fa)); 66 Init(); 67 for (int i=1;i<=m;++i) 68 { 69 int t1,t2; 70 t1=getfa(a[i].x); t2=getfa(a[i].y); 71 if (t1!=t2) 72 { 73 fa[t1]=t2; 74 ans=max(ans,a[i].val); 75 if (getfa(s)==getfa(t)) 76 break; 77 } 78 } 79 printf("%d ",ans); 80 } 81 return 0; 82 }
然后跑了266ms美滋滋
发现有Dalao打的DFS(我上面说的),跑了98ms,这里一并粘上
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 5 typedef long long ll; 6 inline void read (int& s) { 7 s = 0; 8 static char c = getchar (); 9 while (c < ‘0‘ || c > ‘9‘) c = getchar (); 10 while (c >= ‘0‘ && c <= ‘9‘) s = (s << 3) + (s << 1) + (c ^ 48), c = getchar (); 11 return ; 12 } 13 14 const int N = 1003, M = 100003; 15 int n, m, Q, fa[N]; 16 struct kruskal { 17 int x, y, w; 18 inline int operator < (const kruskal& p) const {return w < p.w;} 19 }r[M]; 20 21 int h[N], tot; 22 struct stu { 23 int v; 24 int next; 25 int w; 26 }s[N << 1]; 27 28 inline void add (const int x, const int y, const int z) { 29 ++tot; 30 s[tot].v = y; 31 s[tot].w = z; 32 s[tot].next = h[x]; 33 h[x] = tot; 34 return ; 35 } 36 37 int Find (const int p) {return fa[p] == p ? p : fa[p] = Find (fa[p]);} 38 39 int d[N], f[11][N], mx[11][N]; 40 41 void dfs (const int x, const int pr) { 42 d[x] = d[pr] + 1; 43 int i, y; for (i = 0; i < 10; ++i) { 44 mx[i + 1][x] = max (mx[i][x], mx[i][f[i][x]]); 45 f[i + 1][x] = f[i][f[i][x]]; 46 } 47 for (i = h[x]; i; i = s[i].next) { 48 y = s[i].v; 49 if (y == pr) continue; 50 mx[0][y] = s[i].w; 51 f[0][y] = x; 52 dfs (y, x); 53 } 54 return ; 55 } 56 57 inline int LCA_MAX (int x, int y) { 58 if (d[x] < d[y]) swap (x, y); 59 int MAX = 0, i; 60 for (i = 10; ~i; --i) { 61 if (d[f[i][x]] >= d[y]) { 62 MAX = max (MAX, mx[i][x]); 63 x = f[i][x]; 64 } 65 } 66 if (x == y) return MAX; 67 for (i = 10; ~i; --i) { 68 if (f[i][x] != f[i][y]) { 69 MAX = max (MAX, max (mx[i][x], mx[i][y])); 70 x = f[i][x]; 71 y = f[i][y]; 72 } 73 } 74 return max (MAX, max (mx[0][x], mx[0][y])); 75 } 76 77 int main () { 78 read (n), read (m), read (Q); 79 int i, x, y, z; for (i = 1; i <= m; ++i) 80 read (r[i].x), read (r[i].y), read (r[i].w); 81 sort (r + 1, r + 1 + m); 82 for (i = 1; i <= n; ++i) fa[i] = i; 83 int now = 0, fx, fy; 84 for (i = 1; i <= m; ++i) { 85 fx = Find (r[i].x); 86 fy = Find (r[i].y); 87 if (fx != fy) { 88 fa[fx] = fy; 89 ++now; 90 add (r[i].x, r[i].y, r[i].w); 91 add (r[i].y, r[i].x, r[i].w); 92 if (now == n - 1) break; 93 } 94 } 95 for (i = 1; i <= n; ++i) if (!d[i]) dfs (i, 0); 96 while (Q--) { 97 read (x), read (y); 98 if (Find (x) != Find (y)) puts ("-1"); 99 else printf ("%d ", LCA_MAX (x, y)); 100 } 101 return 0; 102 }
话说我也想到了最优解,但是苦在打不好
我还是太蒟了
以上是关于最小瓶颈路的主要内容,如果未能解决你的问题,请参考以下文章