[NOIp2013] 货车运输
比较水的一道题,之前做过类似的,今天没事儿干,写了这个......
算法很显然了,先求个生成树,在树上跑倍增......
有两个地方被卡了,一个是并查集忘赋初值了,还有就是倍增的时候应该先更新ans,再更新x,我写反了。
如果先更新x,g[x][i]就不是原来那个g[x][i]了,ans也就不对了。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 6 int n,m,q; 7 int hd[10005],to[20005],lim[20005],nx[20005],ec; 8 int ff[10005]; 9 10 int findfa(int p) 11 { 12 if(ff[p]==p)return p; 13 ff[p]=findfa(ff[p]); 14 return ff[p]; 15 } 16 17 struct edge 18 { 19 int ea,eb,elim; 20 }e[50005]; 21 22 int cmp(edge q,edge w) 23 { 24 return q.elim>w.elim; 25 } 26 27 void addedge(int af,int at,int al) 28 { 29 to[++ec]=at; 30 lim[ec]=al; 31 nx[ec]=hd[af]; 32 hd[af]=ec; 33 } 34 35 int d[10005],f[10005][20],g[10005][20]; 36 37 void dfs(int p,int fa,int lm) 38 { 39 f[p][0]=fa; 40 g[p][0]=lm; 41 d[p]=d[fa]+1; 42 for(int i=hd[p];i;i=nx[i]) 43 { 44 if(to[i]!=fa)dfs(to[i],p,lim[i]); 45 } 46 } 47 48 int ask(int x,int y) 49 { 50 int ans=0x3f3f3f3f; 51 if(d[x]<d[y])swap(x,y); 52 for(int i=18;i>=0;i--) 53 if(d[f[x][i]]>=d[y]) 54 ans=min(ans,g[x][i]),x=f[x][i]; 55 if(x==y)return ans; 56 for(int i=18;i>=0;i--) 57 if(f[x][i]!=f[y][i]) 58 ans=min(ans,min(g[x][i],g[y][i])),x=f[x][i],y=f[y][i]; 59 ans=min(ans,min(g[x][0],g[y][0])); 60 return ans; 61 } 62 63 int main() 64 { 65 scanf("%d%d",&n,&m); 66 for(int i=1;i<=m;i++) 67 { 68 scanf("%d%d%d",&e[i].ea,&e[i].eb,&e[i].elim); 69 } 70 sort(e+1,e+1+m,cmp); 71 for(int i=1;i<=n;i++)ff[i]=i; 72 for(int i=1;i<=m;i++) 73 { 74 int fa=findfa(e[i].ea),fb=findfa(e[i].eb); 75 if(fa==fb)continue; 76 ff[fa]=fb; 77 addedge(e[i].ea,e[i].eb,e[i].elim); 78 addedge(e[i].eb,e[i].ea,e[i].elim); 79 } 80 memset(g,0x3f,sizeof(g)); 81 for(int i=1;i<=n;i++) 82 { 83 if(!d[i])dfs(i,0,0x3f3f3f3f); 84 } 85 for(int i=1;i<=18;i++) 86 { 87 for(int j=1;j<=n;j++) 88 { 89 f[j][i]=f[f[j][i-1]][i-1]; 90 g[j][i]=min(g[j][i-1],g[f[j][i-1]][i-1]); 91 } 92 } 93 scanf("%d",&q); 94 for(int i=1;i<=q;i++) 95 { 96 int x,y; 97 scanf("%d%d",&x,&y); 98 int fx=findfa(x),fy=findfa(y); 99 if(fx!=fy)printf("-1\n"); 100 else printf("%d\n",ask(x,y)); 101 } 102 return 0; 103 }