codevs 3287 货车运输 NOIP2013提高组
题目链接:http://codevs.cn/problem/3287/
题解:
和bzoj3732一毛一样,只不过是找最大生成树和最小值罢了,具体参见我的bzoj3732的博客
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 #define MAXN 100010 5 #define MAXM 1000010 6 int n,m,k,heade[MAXN],father[MAXN],fa[20][MAXN],dep[MAXN]; 7 struct edge1 8 { 9 int u,v,val; 10 }e1[MAXM]; 11 struct edge 12 { 13 int v,next,val; 14 }e[MAXM]; 15 int min(int x,int y) 16 { 17 return x<y?x:y; 18 } 19 int find(int x) 20 { 21 return father[x]=father[x]==x?x:find(father[x]); 22 } 23 bool cmp(edge1 a,edge1 b) 24 { 25 return a.val>b.val; 26 } 27 void adde(int i,int x,int y,int z) 28 { 29 e1[i]=(edge1){x,y,z}; 30 } 31 void dfs(int u) 32 { 33 for(int i=heade[u];i;i=e[i].next) 34 { 35 if(!dep[e[i].v]) 36 { 37 dep[e[i].v]=dep[u]+1; 38 fa[0][e[i].v]=u; 39 dfs(e[i].v); 40 } 41 } 42 } 43 int LCA(int u,int v) 44 { 45 if(dep[u]>dep[v])swap(u,v); 46 for(int i=16;~i;i--) 47 if(dep[fa[i][v]]>=dep[u]) 48 v=fa[i][v]; 49 if(u==v)return u; 50 for(int i=16;~i;i--) 51 if(fa[i][u]!=fa[i][v]) 52 { 53 u=fa[i][u]; 54 v=fa[i][v]; 55 } 56 return fa[0][u]; 57 } 58 int main() 59 { 60 scanf("%d%d",&n,&m); 61 int x,y,z; 62 for(int i=1;i<=m;i++) 63 { 64 scanf("%d%d%d",&x,&y,&z); 65 adde(i<<1,x,y,z); 66 adde(i<<1+1,y,x,z); 67 } 68 for(int i=1;i<=n;i++) 69 father[i]=i; 70 sort(e1+1,e1+m*2+1,cmp); 71 int cnt=0; 72 for(int i=1;i<=m*2;i++) 73 { 74 x=find(e1[i].u); 75 y=find(e1[i].v); 76 if(x!=y) 77 { 78 int u=e1[i].u,v=e1[i].v; 79 father[y]=x; 80 ++cnt; 81 e[cnt<<1]=(edge){v,heade[u],e1[i].val}; 82 heade[u]=cnt<<1; 83 e[(cnt<<1)+1]=(edge){u,heade[v],e1[i].val}; 84 heade[v]=(cnt<<1)+1; 85 if(cnt==n-1)break; 86 } 87 } 88 dep[1]=fa[0][1]=1; 89 dfs(1); 90 for(int i=1;i<=16;i++) 91 for(int j=1;j<=n;j++) 92 fa[i][j]=fa[i-1][fa[i-1][j]]; 93 scanf("%d",&k); 94 while(k--) 95 { 96 scanf("%d%d",&x,&y); 97 int lca=LCA(x,y),t=x,ans=2147483647; 98 if(!lca) 99 { 100 printf("-1\n"); 101 continue; 102 } 103 while(t!=lca) 104 { 105 for(int i=heade[t];i;i=e[i].next) 106 { 107 if(dep[e[i].v]<dep[t]) 108 { 109 t=e[i].v; 110 ans=min(ans,e[i].val); 111 break; 112 } 113 } 114 } 115 t=y; 116 while(t!=lca) 117 { 118 for(int i=heade[t];i;i=e[i].next) 119 { 120 if(dep[e[i].v]<dep[t]) 121 { 122 t=e[i].v; 123 ans=min(ans,e[i].val); 124 break; 125 } 126 } 127 } 128 printf("%d\n",ans); 129 } 130 return 0; 131 }