hgoi#20191115

Posted muronglin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hgoi#20191115相关的知识,希望对你有一定的参考价值。

T1-表演

给你一幅既带点权又带边权的无向图
点权表示在这个点完成任务的花费
求从每个点出发到某一个点完成任务再回来的最小花费

解法

最短路模板, (dis) 数组初始赋为点权,然后边权全部乘 (2)

ac代码

#include<bits/stdc++.h>
#define pb push_back
#define ll long long 
using namespace std;
inline void readint(int&x)
{
    x=0;int fh=1;char c=getchar();
    for(;!isdigit(c);c=getchar())if(c=='-')fh=-1;
    for(;isdigit(c);c=getchar())x=x*10+c-'0';
    x*=fh;
}
inline void readll(ll&x)
{
    x=0;ll fh=1;char c=getchar();
    for(;!isdigit(c);c=getchar())if(c=='-')fh=-1;
    for(;isdigit(c);c=getchar())x=x*10+c-'0';
    x*=fh;
}
inline void print(ll x)
{
    if(x>9)print(x/10);
    putchar(x%10+'0');
}
struct node
{
    int id;ll w;
    bool operator<(const node&a)const{return w>a.w;}
};
priority_queue<node>q;
vector<int>e[200010];
vector<ll>w[200010];
int n,m,x,y;
ll z,ans[200010];
bool vis[200010];
void solve()
{
    for(int i=1;i<=n;i++)
        q.push((node){i,ans[i]});
    while(!q.empty())
    {
        node u=q.top();q.pop();
        if(vis[u.id])continue;
        vis[u.id]=1;
        int sz=e[u.id].size();
        for(int i=0;i<sz;i++)
            if(ans[e[u.id][i]]>ans[u.id]+w[u.id][i])
                ans[e[u.id][i]]=ans[u.id]+w[u.id][i],
                q.push((node){e[u.id][i],ans[e[u.id][i]]});
    }
}
int main()
{
    freopen("exciting.in","r",stdin);
    freopen("exciting.out","w",stdout);
    readint(n),readint(m);
    for(int i=1;i<=m;i++)
        readint(x),readint(y),readll(z),z+=z,
        e[x].pb(y),w[x].pb(z),
        e[y].pb(x),w[y].pb(z);
    for(int i=1;i<=n;i++)
        readll(ans[i]);
    solve();
    for(int i=1;i<=n;i++)
        print(ans[i]),putchar(' ');
    fclose(stdin);
    fclose(stdout);
    return 0;
}

T2-逮虾户

你用 (t) 的时间行了 (n) 段路
现在给你每段路的路程以及估计速度
估计速度与真实速度的差值一定
求出这个差值

解法

这就是一个减函数,二分就好了。。。

ac代码

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f 
#define eps (1e-9)
#define epss (1e-20)
using namespace std;
int n;
double t,minn,s[1010],v[1010];
double solve(double d)
{
    double tmp=0.0;
    for(int i=1;i<=n;i++)
        tmp+=s[i]/(v[i]+d);
    return tmp;
}
int main()
{
    freopen("dejavu.in","r",stdin);
    freopen("dejavu.out","w",stdout);
    scanf("%d%lf",&n,&t),minn=inf;
    for(int i=1;i<=n;i++)
        scanf("%lf%lf",&s[i],&v[i]),
        minn=fmin(minn,v[i]);
    double l=eps-minn,r=inf;
    while(r-l>=eps)
    {
        double mid=(l+r)/2.0,tmp=solve(mid);
        if(tmp>=t)l=mid;else r=mid;
    }
    printf("%.9lf",l);
    fclose(stdin);
    fclose(stdout);
    return 0;
}

T3-跳一跳

给你一个数组 (A) ,求它最长的满足奇数项小于两边的偶数项或偶数项小于两边的奇数项的子序列

解法

这就是个贪心,每次放进来一个数如果能增加长度就塞进去,不然就替换这个数

ac代码

#include<bits/stdc++.h>
using namespace std;
inline void read(int&x)
{
    x=0;int fh=1;char c=getchar();
    for(;!isdigit(c);c=getchar())if(c=='-')fh=-1;
    for(;isdigit(c);c=getchar())x=x*10+c-'0';
    x*=fh;
}
inline void print(int x)
{
    if(x>9)print(x/10);
    putchar(x%10+'0');
}
int n,x,lst,opt1,opt2,ans1,ans2;
int main()
{
    freopen("jump.in","r",stdin);
    freopen("jump.out","w",stdout);
    read(n),read(lst),opt2=ans1=ans2=1;
    for(int i=2;i<=n;i++)
    {
        read(x);
        (x>lst)&&(ans1+=!opt1,ans2+=!opt2,opt1=opt2=1);
        (x<lst)&&(ans1+=opt1,ans2+=opt2,opt1=opt2=0);
        lst=x;
    }
    print(max(ans1,ans2));
    fclose(stdin);
    fclose(stdout);
    return 0;
}

以上是关于hgoi#20191115的主要内容,如果未能解决你的问题,请参考以下文章

hgoi#20191109

hgoi#2019/2/16--t2--friend

HGOI 20181028 题解

HGOI 20190711

HGOI 20190828 题解

HGOI 20190310 题解