zoukankan      html  css  js  c++  java
  • 货车运输 vijos 1843 NOIP2013 D1T3 最大生成树,并查集,(伪·LCA)

    本人比较笨,没写LCA,在树上暴力跑过了此题。

    可以证明答案一定在最大生成树上,因为如果答案比最大生成树上的路径更优,那么最大生成树一定不是正确的。反证之。

    同时注意到最大生成树过程中是使用了并查集的,所以不会出现某些点“被丢下”的情况,希望读者不必在此纠结。

    我们跑完最大生成树之后,已经有了一个并查集,我们用并查集来判断两个点是否联通,若两个点不在一个并查集中,那么他们也一定在原图中不联通,直接输出-1即可

    首先记录X到树根路径上每个点的“路径最大限重”,再用y向根跑,若遇到有记录的节点,就取x的记录和y跑的记录的最小值,输出即可。

    附上AC代码

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<cmath>
      5 #include<iostream>
      6 using namespace std;
      7 template<class T> inline void read(T &_a){
      8     bool f=0;int _ch=getchar();_a=0;
      9     while(_ch<'0' || _ch>'9'){if(_ch=='-')f=1;_ch=getchar();}
     10     while(_ch>='0' && _ch<='9'){_a=(_a<<1)+(_a<<3)+_ch-'0';_ch=getchar();}
     11     if(f)_a=-_a;
     12 }
     13 
     14 const int maxn=10001,maxm=50001;
     15 int n,m,egcnt,head[maxn],Q,egcnttt,belong[maxn],fa[maxn],tmp[maxn];
     16 bool vis[maxn];
     17 struct edge {int to,next,dis;}w[maxn<<1];
     18 struct edge2{
     19     int from,to,dis;
     20     inline bool operator < (const edge2 x) const {return dis>x.dis;}
     21 }edg[maxm];
     22 
     23 inline void addedge2(int from,int to,int dis)
     24 {
     25     edg[++egcnttt].to=to;
     26     edg[egcnttt].from=from;
     27     edg[egcnttt].dis=dis;
     28 }
     29 
     30 inline void addedge(int from,int to,int dis)
     31 {
     32     w[++egcnt].to=to;
     33     w[egcnt].next=head[from];
     34     w[egcnt].dis=dis;
     35     head[from]=egcnt;
     36     w[++egcnt].to=from;
     37     w[egcnt].next=head[to];
     38     w[egcnt].dis=dis;
     39     head[to]=egcnt;
     40 }
     41 
     42 int find(int u)
     43 { return belong[u]==u?u:belong[u]=find(belong[u]); }
     44 
     45 inline void kruskal()
     46 {
     47     sort(edg+1,edg+egcnttt+1);
     48     for (register int i=1;i<=n;++i) belong[i]=i;
     49     for (register int i=1;i<=egcnttt&&egcnt<((n-1)<<1);++i)
     50     {
     51         int a1=find(edg[i].from);
     52         int a2=find(edg[i].to);
     53         if(a1!=a2)
     54         {
     55             belong[a1]=a2;
     56             addedge(edg[i].from,edg[i].to,edg[i].dis);
     57         }
     58     }
     59 }
     60 
     61 void dfs_fa(int u)
     62 {
     63     for (register int i=head[u];i;i=w[i].next)
     64         if(!fa[w[i].to]) fa[w[i].to]=u,dfs_fa(w[i].to);
     65 }
     66 
     67 inline int solve(int x,int y)
     68 {
     69     if(!fa[x]) fa[x]=-1,dfs_fa(x);
     70     memset(tmp,0x7f,sizeof(tmp));
     71     tmp[x]=10000000;
     72     while(x!=-1)
     73     {
     74         for (register int i=head[x];i;i=w[i].next)
     75         if(w[i].to==fa[x])
     76         {
     77             tmp[w[i].to]=min(w[i].dis,tmp[x]);
     78             break;
     79         }
     80         x=fa[x];
     81     }
     82     int ans=10000000;
     83     while(y!=-1)
     84     {
     85         if(tmp[y]<=10000000) {ans=min(ans,tmp[y]); break;}
     86         for (register int i=head[y];i;i=w[i].next)
     87         if(w[i].to==fa[y])
     88         {
     89             ans=min(w[i].dis,ans);
     90             break;
     91         }
     92         y=fa[y];
     93     }
     94     return ans;
     95 }
     96 
     97 int main()
     98 {
     99     read(n); read(m);
    100     for (register int i=1,x,y,z;i<=m;++i) read(x),read(y),read(z),addedge2(x,y,z);
    101     kruskal();
    102     for (read(Q);Q;--Q)
    103     {
    104         int x,y;
    105         read(x); read(y);
    106         int a1=find(x);
    107         int a2=find(y);
    108         if(a1!=a2) {printf("-1
    "); continue;}
    109         printf("%d
    ",solve(x,y));
    110     }
    111     return 0;
    112 }
    View Code
  • 相关阅读:
    evernote100个做笔记的好方法
    平衡二叉树的调整模版
    晨间日记的奇迹
    hdu 2952 Counting Sheep
    hdu 1535 Invitation Cards
    poj 3259 Wormholes(spfa)
    poj 2263 Heavy Cargo(floyd)
    poj 3268 Silver Cow Party(SPFA)
    hdu 1690 Bus System
    hdu 3631 Shortest Path(Floyd)
  • 原文地址:https://www.cnblogs.com/jaywang/p/7738204.html
Copyright © 2011-2022 走看看