[NOIp2013] 货车运输

比较水的一道题,之前做过类似的,今天没事儿干,写了这个......

洛谷 P1967 传送门

算法很显然了,先求个生成树,在树上跑倍增......

有两个地方被卡了,一个是并查集忘赋初值了,还有就是倍增的时候应该先更新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 }

 

posted @ 2018-10-03 20:23  cervusky  阅读(144)  评论(0编辑  收藏  举报

Contact with me