最小生成树,1348:【例4-9】城市公交网建设问题,1349:【例4-10】最优布线问题,1351:【例4-12】家谱树

【题目描述】

有一张城市地图,图中的顶点为城市,无向边代表两个城市间的连通关系,边上的权为在这两个城市之间修建高速公路的造价,研究后发现,这个地图有一个特点,即任一对城市都是连通的。现在的问题是,要修建若干高速公路把所有城市联系起来,问如何设计可使得工程的总造价最少?

【代码】

#include<iostream>
#include<algorithm>
using namespace std;
struct ed
{
    int v,u,e;
}f[10001];
bool cmp(ed x,ed y)
{
    return x.e<y.e;
}
int a[10001];
int b(int m)
{
    if(a[m]!=m)
    {
        int te=b(a[m]);
        return te;
    }
    else return m;
}
int main()
{
    int n,t=0,sum=0,ans=0;
    cin>>n>>t;
    for(int i=1;i<=n;i++)
        a[i]=i;
    for(int i=1;i<=t;i++)
    {
        cin>>f[i].v>>f[i].u>>f[i].e;
    }
    sort(f+1,f+1+t,cmp);
    for(int i=1;i<=t;i++)
    {
        int fu,fv;
        fu=b(f[i].u);
        fv=b(f[i].v);
        if(fu!=fv)
        {
            a[fv]=a[fu];
            sum++;
            cout<<f[i].u<<" "<<f[i].v<<endl;
         } 
         if(sum==n-1)break;
    }
    return 0;
 }

【题目描述】

学校有nn台计算机,为了方便数据传输,现要将它们用数据线连接起来。两台计算机被连接是指它们有数据线连接。由于计算机所处的位置不同,因此不同的两台计算机的连接费用往往是不同的。

当然,如果将任意两台计算机都用数据线连接,费用将是相当庞大的。为了节省费用,我们采用数据的间接传输手段,即一台计算机可以间接的通过若干台计算机(作为中转)来实现与另一台计算机的连接。

现在由你负责连接这些计算机,任务是使任意两台计算机都连通(不管是直接的或间接的)。

【代码】

#include<iostream>
#include<algorithm>
using namespace std;
struct ed
{
    int v,u,e;
}f[10001];
bool cmp(ed x,ed y)
{
    return x.e<y.e;
}
int a[10001];
int b(int m)
{
    if(a[m]!=m)
    {
        int te=b(a[m]);
        return te;
    }
    else return m;
}
int main()
{
    int n,t=0,sum=0,ans=0;
    cin>>n;
    for(int i=1;i<=n;i++)
        a[i]=i;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            int s;
            cin>>s;
            if(i!=j&&s!=0)
            {
                f[++t].v=i;
                f[t].u=j;
                f[t].e=s;
            }
        }
    }
    sort(f+1,f+1+t,cmp);
    for(int i=1;i<=t;i++)
    {
        int fu,fv;
        fu=b(f[i].u);
        fv=b(f[i].v);
        if(fu!=fv)
        {
            a[fv]=a[fu];
            sum++;
            ans+=f[i].e;
         } 
         if(sum==n-1)break;
    }
    if(sum!=n-1)
    {
        cout<<-1;
        return 0;
    }
    cout<<ans;
    return 0;
 }

【题目描述】

有个人的家族很大,辈分关系很混乱,请你帮整理一下这种关系。

给出每个人的孩子的信息。

输出一个序列,使得每个人的后辈都比那个人后列出。

【代码】

#include<iostream>
using namespace std;
int fir[100001],nxt[100001],v[100001],w[100001],t;
bool b[100001];
int a[100001],q[100001];
int n;
void add(int x,int y)
{
    nxt[++t]=fir[x];
    fir[x]=t;
 }  
void bfs()
{
    int num=0;
     int head=1,tail=1;
     while(head<=tail)
     {
         num++;
         if(num>n)return;
         for(int i=1;i<=n;i++)
         {
             if(a[i]==0&&b[i]==0)
             {
                 b[i]=1;
                 q[tail]=i;
                 tail++;
                              }
         }
         cout<<q[head]<<" ";     
        for(int j=fir[q[head]];j;j=nxt[j])
        {
            a[w[j]]--;
         }
         head++;
         
         
     }
 }
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        int l;
        while(cin>>l)
        {
            if(l==0)break;
            add(i,l);
            v[t]=i;
            w[t]=l;
            a[w[t]]++;
        }
    }
    bfs();
   return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值