为了生存之九度OJ1008 1009

1008:n个点m条边(有重边),给定边权和选取该边权的花费,求起点s到终点t的最短距离,以及该最短距离所选取的边权下,的花费,最短距离相同时,选择最小花费的输出。

n=1e3 m=1e4

spfa的一点点变形,当最短距离相同时,松弛一下相同的情况下花费最小的就可以了。其余就是spfa,直接用邻接矩阵写了- -都过了。。。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int inf=999999999;
struct node{

int d;
int p;

}dis[1005],g[1005][1005];
bool inq[1005];
int s,t,n,m;

node spfa(int s,int t,int n)
{
    queue<int> q;
    for(int i=1;i<=n;i++)
    {
        dis[i].d=inf;
        dis[i].p=inf;
    }
    memset(inq,0,sizeof(inq));
    dis[s].d=0;
    dis[s].p=0;
    inq[s]=1;
    q.push(s);
    while(!q.empty())
    {
        int now=q.front();
        q.pop();
        inq[now]=0;
        for(int i=1;i<=n;i++)
        {
            if(dis[now].d+g[now][i].d<dis[i].d)
            {
                dis[i].d=dis[now].d+g[now][i].d;
                dis[i].p=dis[now].p+g[now][i].p;
                if(inq[i]==0)
                {
                    inq[i]=1;
                    q.push(i);
                }
            }
            if(dis[now].d+g[now][i].d==dis[i].d&&dis[now].p+g[now][i].p<dis[i].p)//如果最短距离相同,更新最小花费
            {
                 dis[i].p=dis[now].p+g[now][i].p;
            }

        }
    }
    return dis[t];
}

int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==0&&m==0)
            return 0;
        for(int i=1;i<1005;i++)
        {
            for(int j=1;j<1005;j++)
            {
                g[i][j].d=inf;
                g[i][j].p=inf;
            }
        }
        for(int i=0;i<m;i++)
        {
            int a,b,c,pp;
            scanf("%d%d%d%d",&a,&b,&c,&pp);
            if(c<g[a][b].d)//重边处理。
            {
                g[a][b].d = c;
                g[b][a].d = c;
                g[a][b].p = pp;
                g[b][a].p = pp;
            }
        }
        scanf("%d%d",&s,&t);
        spfa(s,t,n);
        printf("%d %d\n",dis[t].d,dis[t].p);
    }
    return 0;
}



1009:求两棵二叉搜索树是不是完全相同的。

思路:数组模拟递归写,感谢BUG教我这个不会数据结构不会DFS的纱布写。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
const int maxn=25;

struct BST{

    int arr[maxn];//输入进来的数放进去
    int lpos[maxn];//左儿子的位置
    int rpos[maxn];//右儿子的位置
    int cnt;//树中节点个数
    void dfs(int now,int x)
    {
        if(arr[now]>x)
        {
            if(lpos[now]!=-1)//如果左儿子这里已经有元素了
            {
                dfs(lpos[now],x);//就继续向下一层递归
            }
            else
            {
                arr[cnt++]=x;//否则记录下当前的元素
                lpos[now]=cnt-1;//左儿子的位置就是元素个数-1,初始位置为0
            }
        }
        else
        {
            if(rpos[now]!=-1)
            {
                dfs(rpos[now],x);
            }
            else
            {
                arr[cnt++]=x;
                rpos[now]=cnt-1;
            }
        }
    }
    void add_node(int x)
    {
        if(cnt==0)//存根节点
        {
            arr[cnt++]=x;
        }
        dfs(0,x);//从根节点位置出发去递归添加。
    }
    BST()
    {
        memset(lpos,-1,sizeof(lpos));
        memset(rpos,-1,sizeof(rpos));
        cnt=0;
    }
    BST(const string& s)
    {
         memset(lpos,-1,sizeof(lpos));
        memset(rpos,-1,sizeof(rpos));
        cnt=0;
        for(int i=0;i<s.size();i++)
        {
            add_node(s[i]-'0');
        }
    }

}bsta,bstb;


bool isequ(int nowa,int nowb)
{
    if(bsta.arr[nowa]!=bstb.arr[nowb])
    {
        return false;
    }
    if(bsta.lpos[nowa]==-1||bstb.lpos[nowb]==-1)//已经递归到最后了
    {
        if(bsta.lpos[nowa]!=bstb.lpos[nowb])
        return false;
    }
    else if(!isequ(bsta.lpos[nowa],bstb.lpos[nowb]))//还没递归到最后但是所对应的节点编号不同
        return false;

    if(bsta.rpos[nowa]==-1||bstb.rpos[nowb]==-1)
    {
        if(bsta.rpos[nowa]!=bstb.rpos[nowb])
        return false;
    }
    else if(!isequ(bsta.rpos[nowa],bstb.rpos[nowb]))
        return false;
    return true;
}
string a,b;
int main()
{
    int n;
    while(cin>>n)
    {
        if(n==0)
            return 0;
        cin>>a;
        bsta=BST(a);
        while(n--)
        {
            cin>>b;
            bstb=BST(b);
            if(isequ(0,0))
            {
                puts("YES");
            }
            else
            {
                puts("NO");
            }
        }
    }

    return 0;
}

完全不知道研究生机试的题目难度到底是啥,迫于生计,只有刷一波九度OJ上的题目了,把基础打好啊,否则感觉要完,太纱布了。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值