好久不写博客了…我都忘了怎么写了…现在重新开启已经荒废的博客!
这个坑也是好久才填上…
经过这两天的观察,我发现写货车运输题解的博文访问量都好高QAQ
于是我也赶紧来写一发
题目描述 Description
A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。
输入描述 Input Description
第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道路。
接下来 m 行每行 3 个整数 x、y、z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条限重为 z 的道路。注意:x 不等于 y,两座城市之间可能有多条道路。
接下来一行有一个整数 q,表示有 q 辆货车需要运货。
接下来 q 行,每行两个整数 x、y,之间用一个空格隔开,表示一辆货车需要从 x 城市运输货物到 y 城市,注意:x 不等于 y。
输出描述 Output Description
输出共有 q 行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。如果货车不能到达目的地,输出-1。
因为是找最小边的权值最大,所以最优解肯定会在最大生成树中。如果不在最大生成树中,答案肯定要更劣。在跑kruskal的过程中,把边权加和的操作改为建图操作,重新建图后暴力查询lca即可【因为我弱不会倍增
希望各路大神不要吐槽 大蒟蒻写博客不容易啊QAQ
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAX_V=10000+50;
const int MAX_E=50000+50;
int c[MAX_V],first[MAX_V],next[MAX_E<<1],deep[MAX_V],fa[MAX_V],lcaf[MAX_V];
int tot=0,V,E;
struct edge{
int from,to,cost;
}es[MAX_E<<1];
edge es2[MAX_E<<1];
int find(int x)
{
if(fa[x]==x)
return x;
else return find(fa[x]);
}
bool cmp(edge a, edge b)
{
return a.cost>b.cost;
}
void build(int ff,int tt,int dd)
{
es2[++tot]=(edge){ff,tt,dd};
next[tot]=first[ff];
first[ff]=tot;
}
void kruskal()
{
memset(first,-1,sizeof(first));
for(int i=1;i<=V;i++)
fa[i]=i;
sort(es+1,es+1+E,cmp);
for(int i=1;i<=E;i++)
{
int fx=find(es[i].from);
int fy=find(es[i].to);
if(fx!=fy)
{
fa[fx]=fy;
build(es[i].from,es[i].to,es[i].cost);
build(es[i].to,es[i].from,es[i].cost);
}
}
}
void dfs(int u,int f,int val)
{
lcaf[u]=f;
deep[u]=deep[f]+1;
c[u]=val;
for(int i=first[u];i!=-1;i=next[i])
{
int v=es2[i].to;
if(v!=f)
dfs(v,u,es2[i].cost);
}
}
int ask(int x,int y)
{
int ans=0x3f3f3f3f;
if(deep[x]<deep[y])
swap(x,y);
while(deep[x]!=deep[y])
{
ans=min(ans,c[x]);
x=lcaf[x];
}
while(x!=y)
{
ans=min(ans,c[x]);
ans=min(ans,c[y]);
x=lcaf[x];
y=lcaf[y];
}
return ans;
}
int main()
{
cin>>V>>E;
for(int i=1;i<=E;i++)
{
int f,t,d;
scanf("%d%d%d",&f,&t,&d);
es[i]=(edge){f,t,d};
}
kruskal();
int q;
cin>>q;
for(int i=1;i<=q;i++)
{
int x,y;
scanf("%d%d",&x,&y);
int fx=find(x);
int fy=find(y);
if(fx!=fy)
cout<<"-1"<<endl;
else
{
for(int i=1;i<=V;i++)
if(!deep[i])
{
//cout<<i<<endl;
dfs(i,0,0x3f3f3f3f);
}
cout<<ask(x,y)<<endl;
}
}
return 0;
}
/*
4 3
1 2 4
2 3 3
3 1 1
3
1 3
1 4
1 3
*/
2016.10.10 我终于用倍增A掉了这个题…
本来以为只要改一小下就可以,结果一个上午没了QAQ。
思路上面都说了,还是看代码吧QwQ。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX_V=10000+10;
const int MAX_E=50000+10;
struct edge{
int from,to,cost;
}es[MAX_E<<1];
int n,m;
int tot;
int fa[MAX_V];
int find(int x)
{
if(fa[x]==x)
return x;
else
return fa[x]=find(fa[x]);
}
bool cmp(edge a, edge b)
{
return a.cost>b.cost;
}
int first2[MAX_V],nxt2[MAX_E];
struct edge2{
int from,to,cost;
}es2[MAX_E<<1];
int tot2;
void init2()
{
memset(first2,-1,sizeof(first2));
tot2=0;
}
void build2(int ff,int tt,int dd)
{
es2[++tot2]=(edge2){ff,tt,dd};
nxt2[tot2]=first2[ff];
first2[ff]=tot2;
}
void kruskal()
{
for(int i=1;i<=n;i++)
fa[i]=i;
sort(es+1,es+1+m,cmp);
for(int i=1;i<=m;i++)
{
//cout<<es[i].cost<<"********"<<endl;
int fx=find(es[i].from);
int fy=find(es[i].to);
int val=es[i].cost;
if(fx!=fy)
{
fa[fx]=fy;
build2(fx,fy,val);
build2(fy,fx,val);
}
}
}
int dis[MAX_V][30];
int deep[MAX_V];
int father[MAX_V][30];
void dfs(int u,int f,int val)
{
// cout<<u<<" "<<f<<" "<<val<<endl;
// puts("233");
deep[u]=deep[f]+1;
dis[u][0]=val;
father[u][0]=f;
for(int i=1;i<=20;i++)
{
father[u][i]=father[father[u][i-1]][i-1];
dis[u][i]=min(dis[u][i-1],dis[father[u][i-1]][i-1]);
}
for(int i=first2[u];i!=-1;i=nxt2[i])
{
int v=es2[i].to;
//cout<<v<<endl;
if(v==f)
continue;
dfs(v,u,es2[i].cost);
}
}
int lca(int x,int y)
{
if(deep[x]<deep[y])
swap(x,y);
if(deep[x]>deep[y])
{
int t=deep[x]-deep[y];
for(int i=20;i>=0;i--)
{
if(t&(1<<i))
x=father[x][i];
}
}
if(x!=y)
{
for(int i=20;i>=0;i--)
{
if(father[x][i]!=father[y][i])
{
x=father[x][i];
y=father[y][i];
}
}
}
else return x;
return father[x][0];
}
int ask(int x,int f)
{
int ans=0x3f3f3f3f;
int t=deep[x]-deep[f];
for(int i=0;i<=16;i++)
{
if(t&(1<<i))
{
ans=min(ans,dis[x][i]);
x=father[x][i];
}
}
return ans;
}
int main()
{
init2();
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int ff,tt,dd;
scanf("%d%d%d",&ff,&tt,&dd);
es[i]=(edge){ff,tt,dd};
}
kruskal();
int q;
scanf("%d",&q);
for(int i=1;i<=n;i++)
{
if(!deep[i])
dfs(i,0,0x3f3f3f3f);
}
while(q--)
{
int ff,tt;
scanf("%d%d",&ff,&tt);
int fx=find(ff);
int fy=find(tt);
if(fx!=fy)
puts("-1");
else
{
int t=lca(ff,tt);
printf("%d\n",min(ask(ff,t),ask(tt,t)));
}
}
return 0;
}
/*
5 7
4 3 4440
3 1 22348
1 3 28368
2 4 25086
5 3 6991
4 3 10638
3 1 11106
4
4 5
1 3
5 4
2 5
*/