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(){;}
只要是活着的东西,就算是神我也杀给你看。