码迷,mamicode.com
首页 > 其他好文 > 详细

hgoi#20191115

时间:2019-11-15 14:27:07      阅读:55      评论:0      收藏:0      [点我收藏+]

标签:inline   偶数   一个   最小花费   define   lin   int   scanf   using   

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

标签:inline   偶数   一个   最小花费   define   lin   int   scanf   using   

原文地址:https://www.cnblogs.com/muronglin/p/hgoi-20191115.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!