洛谷10月月赛参·最后的狂欢

第一题 60
第二题 100
第三题 50
第四题 100
所以只贴AC代码咯~




**

T2

**

题目描述 Description

**
博艾市将要举行一场汽车拉力比赛。
赛场凹凸不平,所以被描述为M*N的网格来表示海拔高度(1≤ M,N ≤500),每个单元格的海拔范围在0到10^9之间。
其中一些单元格被定义为路标。组织者希望给整个路线指定一个难度系数D,这样参赛选手从任一路标到达别的路标所经过的路径上相邻单元格的海拔高度差不会大于D。也就是说这个难度系数D指的是保证所有路标相互可达的最小值。任一单元格和其东西南北四个方向上的单元格都是相邻的。
**

输入输出格式 Input/output

**
输入格式:
第一行两个整数M和N。第2行到第M+1行,每行N个整数描述海拔高度。第2+M行到第1+2M
行,每行N个整数,每个数非0即1,1表示该单元格是一个路标。


输出格式:
一个整数,即赛道的难度系数D。
**

输入输出样例 Sample input/output

**
**

题解

**
最小生成树,rank维护当前集合里有没有目标点,合并的时候判断一下就可以了(他们的代码大部分都是DP啊,不知道怎么想的)

**

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;

const int maxn=510*510;
struct data{int u,v,w;}e[maxn*2];
int par[maxn],rank[maxn],ma[510][510],cnt,n,m,ans;
bool map[510][510];
void ins(int u,int v,int w){cnt++;e[cnt].v=v;e[cnt].u=u;e[cnt].w=w;}
void ini()
{
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            par[(i-1)*m+j]=(i-1)*m+j;
            rank[(i-1)*m+j]=map[i][j];
        }
    }
}
int find(int x){return x==par[x]?x:par[x]=find(par[x]);}
bool unite(int x,int y){x=find(x);y=find(y);par[y]=x;if(rank[x]&&rank[y])return true;rank[x]+=rank[y];return false;}
bool same(int x,int y){return find(x)==find(y);}
inline bool cmp(data a,data b){return a.w<b.w;}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)scanf("%d",&ma[i][j]);
    for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)scanf("%d",&map[i][j]);
    ini();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            if(i==n&&j==m)continue;
            if(i!=n)ins((i-1)*m+j,i*m+j,abs(ma[i][j]-ma[i+1][j]));
            if(j!=m)ins((i-1)*m+j,(i-1)*m+j+1,abs(ma[i][j]-ma[i][j+1]));
        }
    int ans=0;
    sort(e+1,e+1+cnt,cmp);
    for(int i=1;i<=cnt;i++)
    {
        int u=e[i].u,v=e[i].v,w=e[i].w;
        if(same(u,v))continue;
        if(unite(u,v))ans=w;
    }
    printf("%d",ans);
    return 0;
}

**

T4

**
tarjan缩一下点,然后跑spfa,然后就没有然后了……

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <iostream>
using namespace std;

const int maxn=80010,maxm=200010;
struct data{int to,next,w;double p;}e[maxm];
int head[maxn],h[maxn],cnt,n,m,S,dfn[maxn],low[maxn],time,belong[maxn],q[maxn],top,scc;
bool inq[maxn],del[maxn];
long dis[maxn],ans,val[maxn];
void ins(int u,int v,int w,double p){cnt++;e[cnt].p=p;e[cnt].to=v;e[cnt].next=head[u];head[u]=cnt;e[cnt].w=w;}

struct edge{int to,next,w;}ed[maxm];
void insert(int u,int v,int w){cnt++;ed[cnt].to=v;ed[cnt].next=h[u];h[u]=cnt;ed[cnt].w=w;}
void tarjan(int t)
{
    int now=top;
    q[++top]=t;
    dfn[t]=low[t]=++time;
    inq[t]=1;
    for(int i=head[t];i;i=e[i].next)
        if(!dfn[e[i].to])tarjan(e[i].to),low[t]=min(low[t],low[e[i].to]);
        else if(inq[e[i].to])low[t]=min(low[t],dfn[e[i].to]);
    if(dfn[t]==low[t])
    {
        scc++;
        del[scc]=1;
        while(now!=top)
        {
            belong[q[top]]=scc;
            inq[q[top]]=0;
            top--;
        }
    }
}
void build()
{
    cnt=0;
    for(int t=1;t<=n;t++)
        for(int i=head[t];i;i=e[i].next)
            if(belong[t]!=belong[e[i].to])
                insert(belong[t],belong[e[i].to],e[i].w);
            else
            {
                int sum=e[i].w;
                while(sum)
                {
                    val[belong[t]]+=sum;
                    sum=(int)(sum*e[i].p);
                }
            }
}
void spfa(){
    memset(inq,0,sizeof(inq));
    queue<int> q;
    q.push(S);
    dis[S]=val[S];
    inq[S]=1;
    while(!q.empty())
    {
        int u=q.front();q.pop();
        for(int i=h[u];i;i=ed[i].next)
            if(dis[ed[i].to]<dis[u]+ed[i].w+val[e[i].to])
            {
                dis[ed[i].to]=dis[u]+ed[i].w+val[ed[i].to];
                if(!inq[ed[i].to])
                {
                    inq[ed[i].to]=1;
                    q.push(ed[i].to);
                }
            }
        inq[u]=0;
    }
    for(int i=1;i<=scc;i++)ans=max(ans,dis[i]);
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int u,v,w;double f;
        scanf("%d%d%d%lf",&u,&v,&w,&f);
        ins(u,v,w,f);
    }
    for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);
    build();
    scanf("%d",&S);
    S=belong[S];
    memset(inq,0,sizeof(inq));
    spfa();
    cout<<ans;
    return 0;
}

不要直接复制代码哟~因为会CE的~~希望你们不要和我一样声明time的变量……(cry-ing)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值