cogs1439 货车运输 LCA

填坑进行时……链接:http://cogs.pro/cogs/problem/problem.php?pid=1439

题意:找出两点间最短路上最大的货运量。

这题正解是网络流图论里的东西。首先我们可以想到一个图里面,边权最大的边一定是在这个图的最大生成树上面的,那么我们就先跑出最大生成树。

跑完后,两点间最大边权就可以直接用$LCA$动态查询即可。

 

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 using namespace std;
  6 const int maxn=10005,maxm=50005;
  7 int fa[maxn];
  8 int getfa(int x)
  9 {
 10     return fa[x]==x?x:fa[x]=getfa(fa[x]);
 11 }
 12 void unionn(int x,int y)
 13 {
 14     x=getfa(x),y=getfa(y);
 15     if(x!=y)fa[y]=x;
 16 }
 17 struct node
 18 {
 19     int from,to,dis,next;
 20 }edge[maxn<<1],tmp[maxm];
 21 int head[maxn],tot;
 22 void addedge(int u,int v,int w)
 23 {
 24     edge[++tot]=(node){u,v,w,head[u]};head[u]=tot;
 25 }
 26 int cmp(const node &a,const node &b)
 27 {
 28     return a.dis>b.dis;
 29 }
 30 int n,m,q;
 31 void Kruskal()
 32 {
 33     for(int i=1;i<=n;i++)fa[i]=i;
 34     int cnt=0;
 35     sort(tmp+1,tmp+m+1,cmp);
 36     for(int i=1;i<=m;i++)
 37     {
 38         int u=tmp[i].from,v=tmp[i].to;
 39         if(getfa(u)!=getfa(v))
 40         {
 41             unionn(u,v);
 42             int w=tmp[i].dis;
 43             addedge(u,v,w);addedge(v,u,w);cnt++;
 44             if(cnt==n-1)break;
 45         }
 46     }
 47 }
 48 int p[maxn][32],dep[maxn],dis[maxn][32];
 49 void dfs(int u,int dept,int fa)
 50 {
 51     dep[u]=dept;
 52     for(int i=head[u];i;i=edge[i].next)
 53     {
 54         int v=edge[i].to;
 55         if(v!=p[u][0])
 56         {
 57             p[v][0]=u;dis[v][0]=edge[i].dis;
 58             dfs(v,dept+1,fa);
 59         }
 60     }
 61 }
 62 void init()
 63 {
 64     for(int i=1;(1<<i)<=n;i++)
 65         for(int j=1;j<=n;j++)p[j][i]=-1,dis[j][i]=2147483647;
 66     for(int j=1;(1<<j)<=n;j++)
 67         for(int i=1;i<=n;i++)
 68             if(p[i][j-1]!=-1)p[i][j]=p[p[i][j-1]][j-1],dis[i][j]=min(dis[i][j-1],dis[p[i][j-1]][j-1]);
 69 }
 70 int lca(int x,int y)
 71 {
 72     int i,res=2147483647;if(dep[x]<dep[y])swap(x,y);
 73     for(i=0;(1<<i)<=dep[x];i++);i--;
 74     for(int j=i;j>=0;j--)
 75         if(dep[x]-(1<<j)>=dep[y])res=min(res,dis[x][j]),x=p[x][j];
 76     if(x!=y)
 77     {
 78         for(int j=i;j>=0;j--)
 79             if(p[x][j]!=p[y][j])res=min(res,min(dis[x][j],dis[y][j])),x=p[x][j],y=p[y][j];
 80         res=min(res,min(dis[x][0],dis[y][0]));
 81     }
 82     return res;
 83 }
 84 int haha()
 85 {
 86     freopen("truck.in","r",stdin);
 87     freopen("truck.out","w",stdout);
 88     scanf("%d%d",&n,&m);
 89     for(int i=1;i<=m;i++)
 90     {
 91         int x,y,z;scanf("%d%d%d",&x,&y,&z);
 92         tmp[i]=(node){x,y,z,0};
 93     }
 94     Kruskal();dfs(1,1,0);init();
 95     scanf("%d",&q);
 96     for(int i=1;i<=q;i++)
 97     {
 98         int x,y;scanf("%d%d",&x,&y);
 99         if(getfa(x)!=getfa(y))puts("-1");
100         else printf("%d\n",lca(x,y));
101     }
102 }
103 int sb=haha();
104 int main(){;}
cogs1439

 

posted @ 2017-08-11 21:01  ccc000111  阅读(136)  评论(0编辑  收藏  举报