codevs 1519 过路费(最小生成树+LCA)

http://blog.csdn.net/loi_yzs/article/details/52938283

正解:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXV=10100;
const int MAXE=101000;
int first[MAXV],nxt[MAXE<<1];
int dis[MAXV],deep[MAXV],fa[MAXV],f[MAXV];
int n,m,q,tot;
bool used[MAXV];
struct edge
{
    int from,to,cost;
}es[MAXE<<1],c[MAXE<<1];
bool cmp(edge a,edge b)
{
    return a.cost<b.cost;
}
void init()
{
    memset(first,-1,sizeof(first));
    for(int i=1;i<=n;i++) f[i]=i;
    tot=0;
}
void build(int f,int t,int d)
{
    es[++tot]=(edge){f,t,d};
    nxt[tot]=first[f];
    first[f]=tot;
}
int find(int x)
{
    return f[x]==x?x:f[x]=find(f[x]);
}
void dfs(int s)
{
    used[s]=1;
    for(int i=first[s];i!=-1;i=nxt[i])
    {
        int v=es[i].to;
        if(!used[v])
        {
            fa[v]=s;
            deep[v]=deep[s]+1;
            dis[v]=es[i].cost;
            dfs(v);
        }
    }
}
int lca(int x,int y)//利用lca的想法
{
    int maxx=0;//利用lca找路径上的最大值 
    if(deep[x]>deep[y]) swap(x,y);
    while(deep[x]!=deep[y])
    {
        if(dis[y]>maxx) maxx=dis[y];
        y=fa[y];
    }
    while(x!=y)
    {
        if(dis[x]>maxx) maxx=dis[x];
        if(dis[y]>maxx) maxx=dis[y];
        x=fa[x];
        y=fa[y];
    }
    return maxx;
}
int main()
{
    scanf("%d%d",&n,&m);
    init();
    for(int i=1;i<=m;i++)
        scanf("%d%d%d",&c[i].from,&c[i].to,&c[i].cost);
    sort(c+1,c+m+1,cmp);//最小生成树 
    for(int i=1;i<=m;i++)
    {
        int u=find(c[i].from);
        int v=find(c[i].to);
        if(u!=v)
        {
            f[u]=v;
            build(c[i].from,c[i].to,c[i].cost);
            build(c[i].to,c[i].from,c[i].cost);
        }
    }
    dfs(1);//建树 
    scanf("%d",&q);
    for(int i=1;i<=q;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        printf("%d\n",lca(u,v));
    }
    return 0;
}//没什么好说的╮(╯▽╰)╭

查不出来区别….wa

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,fa[10005],cnt,tot,head[10005],fath[10005],q,x,y,dep[10005],dis[10005];
bool used[10005];
struct Edge{
    int from,to,cost,next;
    bool flag;
}e[200005],ex[200005];
bool cmp(Edge x,Edge y)
{
    return x.cost<y.cost ;
}
int find(int x)
{
    if(x==fa[x]) return fa[x];
    else return fa[x]=find(fa[x]);
}
void addedge(int fn,int tn,int ct)
{
    tot++;
    ex[tot].from=fn;//这里要新建一个ex[] 
    ex[tot].to=tn;
    ex[tot].cost=ct;
    ex[tot].next=head[fn];
    head[fn]=tot;
}
void mst()
{
    for(int i=1;i<=n;i++) fa[i]=i;

    for(int i=1;i<=m;i++)
    {
        if(find(e[i].from) !=find(e[i].to))
        {
            cnt++;
            fa[e[i].to]=e[i].from;//这个fa并查集用 
            addedge(e[i].from,e[i].to,e[i].cost);
            addedge(e[i].to,e[i].from,e[i].cost);
        }
        if(cnt==n-1)//只有这么多边了 
            break;
    }   
}
void dfs(int u)
{
    used[u]=1;
    for(int i=head[u];i>0;i=ex[i].next)
    {
        int v=ex[i].to;
        if(!used[v])
        {
            fath[v]=u;//这个fath单纯的记录父亲 
            dep[v]=dep[u]+1;
            dis[v]=ex[i].cost;//
            dfs(v);//
        }
    }
}
int lca(int x,int y)
{
    int mx=0;
    if(dep[x]>dep[y]) swap(x,y);
    while(dep[x]!=dep[y])
    {
        if(dis[y]>mx) mx=dis[y];
        y=fath[y];//一个一个往上爬的... /
    }
    while(x!=y)//爬到相同高度再同时爬 
    {
        if(dis[x]>mx) mx=dis[x];
        if(dis[y]>mx) mx=dis[y];
        x=fath[x];
        y=fath[y];
    } 
    return mx; 
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&e[i].from,&e[i].to,&e[i].cost);
    }
    sort(e+1,e+m+1,cmp);  
    mst();

//    cout<<endl;
//    for(int i=1;i<=tot;i++)
//      cout<<e[i].from<<","<<e[i].to<<endl;
//    cout<<endl;

    dfs(1);
    scanf("%d",&q);
    for(int i=1;i<=q;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        printf("%d\n",lca(x,y));
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值