学习日记:2022年2月13日

今天的第一个题

如果我们有这样的一组数据

9 11
7 8
8 9
9 7
4 1
7 3
1 2
2 5
5 6
6 2
1 3
3 4

为了更好的对照,我们把相应的关系图也给画出来

差不多就是上面这样

从图来看我们是能够直接看出来,1-2和3-7

其他不满足条件的路基本都有一个共同特征,能够与其他的路连接成一个闭合的环

所以我们就可以通过排除所有闭合的环上的路线,剩余的路线就是最终的结果

为了满足题目要求的输出,我们肯定是要排序的。

1 2
1 3
1 4
2 5
2 6
3 4
3 7
5 6
7 8
7 9
8 9

假设我们从城市1开始走,走的方法就是深度优先算法

从1往下走1-2走到2

判断城市2是否是走过的城市,不是就继续往下走

从2往下走2-5走到5

判断城市5是否是走过的城市,不是,继续往下走

从5往下走5-6,走到6

判断城市6是否是走过的城市,不是,继续往下走

从6往下走6-2,走到2

判断城市2是否是走过的城市,是。说明前面形成了一个环,往前面找,找到起点为2的路线,并将沿途的所有路线都做标记

所以包括本身,以及沿途上的2-6,5-6,2-5都进行标记

所以从1-2以上的所有路线都遍历完了

然后从1-3的路线开始走

判断城市3,继续往下走-7

判断城市7,继续往下走-8

判断城市8,继续往下走-9

判断城市9,继续往下走-7

判断城市7,已经走过了,标记沿途的路线7-9,8-9,7-8

我们继续从城市3走,往下走-4

判断城市4,继续往下走-1

判断城市1,已经走过了,标记沿途的路线1-3,3-4,1-4

所有的路线都判断完毕,最终输出没有标记的路线

1-2和3-7 

其中是需要好几个标记

一个标记走过的路线,

一个标记走过的城市

一个标记成环的路线

最终的代码如下

#include<iostream>
using namespace std;
struct Data
{
    int a;
    int b;
}data[5003];
int don[5003]={0};//标记走过的路线
int result[5003]={0};//记录最终结果
int steep[200];//记录已经走过的城市
int n,m;
int run(int start,int end)
{
    int mid=(start+end)/2;
    int a=start;
    int b=mid+1;
    Data shadow[5003];
    int len=0;
    while(a<=mid&&b<=end)
    {
        if(data[a].a<data[b].a)
        {
            shadow[len++]=data[a++];
        }
        else
        if(data[a].a==data[b].a)
        {
            if(data[a].b<data[b].b)
            shadow[len++]=data[a++];
            else
            shadow[len++]=data[b++];
        }
        else
        shadow[len++]=data[b++];
    }
    while(a<=mid)
    shadow[len++]=data[a++];
    while(b<=end)
    shadow[len++]=data[b++];
    for(int i=0;i<len;i++)
    data[start+i]=shadow[i];
}
int sorting(int start,int end)
{
    if(start>=end)
    return 0;
    int mid=(start+end)/2;
    sorting(start,mid);
    sorting(mid+1,end);
    run(start,end);
}



//标记沿途的路线
int clear(int present,int goal,int flag)
{
    result[present]=1;
    if(flag==0)
    if(data[present].a==goal||data[present].b==goal)
    return 0;
    present=don[present];
    clear(present,goal,0);
}
int finding(int present,int cit)
{
    if(steep[cit])
    {
        clear(present,cit,1);
        return 0;
    }
    for(int i=1;i<=m;i++)
    {
        if(don[i]==0)
        {
            if(data[i].a==cit)
            {
                don[i]=present;//标记走过的路线,记录上一步
                steep[data[i].a]=1;//标记走过的城市
                finding(i,data[i].b);//前往下一个城市
            }
            if(data[i].b==cit)
            {
                don[i]=present;//标记走过的路线,记录上一步
                steep[data[i].b]=1;//标记走过的城市
                finding(i,data[i].a);//前往下一个城市                
            }
        }
    }
}
int main()
{
    cin>>n>>m;
    int a,b;
    for(int i=1;i<=m;i++)
    {
        cin>>a>>b;
        //存入时a必须小于b
        if(a>b)
        data[i].a=b,data[i].b=a;
        else
        data[i].a=a,data[i].b=b;
    }
    sorting(1,m);//排序
    finding(1,data[1].a);
    for(int i=1;i<=m;i++)
    {
        if(result[i]==0)
        cout<<data[i].a<<' '<<data[i].b<<endl;
    }
}

总结下来这一个题就是并查集,深度优先算法的集合。

主要还是深度优先算法

根据探索出来的特殊条件执行特殊命令,得出最终的结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值