zoukankan      html  css  js  c++  java
  • 最小瓶颈路

    题目链接:最小瓶颈路

    首先,这是一道无脑题

    话说我上学校正常信息课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 }
    大佬的代码

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

    我还是太蒟了

  • 相关阅读:
    Spring AOP中pointcut expression表达式解析
    java中Action层、Service层和Dao层的功能区分
    vim对erlang语法支持
    svn跳过某个目录
    时间,闰秒,及NTP
    grep
    【转】MySql数据库--mysql_real_escape_string()函数
    Linux sed 批量替换多个文件中的字符串
    求最大公约数
    怎么利用SQL语句查询数据库中具体某个字段的重复行
  • 原文地址:https://www.cnblogs.com/cptbtptpbcptbtptp/p/11684608.html
Copyright © 2011-2022 走看看