最小瓶颈路

题目链接:最小瓶颈路

首先,这是一道无脑题

话说我上学校正常信息课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\n",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\n", LCA_MAX (x, y));
100     }
101     return 0;
102 }
大佬的代码

话说我也想到了最优解,但是苦在打不好

我还是太蒟了

posted @ 2019-10-16 11:48  LyingFlat666  阅读(216)  评论(0编辑  收藏  举报