zoukankan      html  css  js  c++  java
  • bzoj 1045 [HAOI2008] 糖果传递——设变量推式子

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1045

    费用流TLE。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define ll long long
    using namespace std;
    const int N=1e6+5;
    const ll INF=1e15;
    int n,a[N],hd[N],xnt=1,pre[N],dis[N];
    ll ans,base;
    bool vis[N];
    struct Ed{
        int nxt,to,w;
        ll cap;
        Ed(int n=0,int t=0,ll c=0,int w=0):nxt(n),to(t),cap(c),w(w) {}
    }ed[N<<4];
    int rdn()
    {
        int ret=0;char ch=getchar();
        while(ch>'9'||ch<'0')ch=getchar();
        while(ch>='0'&&ch<='9')(ret*=10)+=ch-'0',ch=getchar();
        return ret;
    }
    void add(int x,int y,ll cap)
    {
        int k=1;if(!x||y==n+1)k=0;
        ed[++xnt]=Ed(hd[x],y,cap,k);hd[x]=xnt;
        ed[++xnt]=Ed(hd[y],x,0,-k);hd[y]=xnt;
    }
    queue<int> q;
    bool spfa()
    {
        q.push(0);vis[0]=1;
        memset(dis,0x3f,sizeof dis);dis[0]=0;
        while(q.size())
        {
            int k=q.front();q.pop();vis[k]=0;
            for(int i=hd[k],v;i;i=ed[i].nxt)
                if(ed[i].cap&&dis[v=ed[i].to]>dis[k]+ed[i].w)
                {
                    dis[v]=dis[k]+ed[i].w;
                    pre[v]=i;
                    if(!vis[v])vis[v]=1,q.push(v);
                }
        }
        return dis[n+1]<0x3f3f3f3f;
    }
    void ek()
    {
        ll flow=INF;
        for(int i=n+1;i;i=ed[pre[i]^1].to)
            flow=min(flow,ed[pre[i]].cap);
        for(int i=n+1;i;i=ed[pre[i]^1].to)
            ed[pre[i]].cap-=flow,ed[pre[i]^1].cap+=flow;
        ans+=flow*dis[n+1];
    }
    int main()
    {
        n=rdn();
        for(int i=1;i<=n;i++)a[i]=rdn(),base+=a[i];
        base/=n;
        for(int i=1;i<=n;i++)
        {
            if(a[i]>base)add(0,i,a[i]-base);
            if(a[i]<base)add(i,n+1,base-a[i]);
            add(i,i-1?i-1:n,INF);add(i,i+1<=n?i+1:1,INF);
        }
        while(spfa())ek();
        printf("%lld
    ",ans);
        return 0;
    }
    View Code

    TJ:http://hzwer.com/2656.html

    为了计算出每个人传递出去的糖果数量,需要先把它们设出来。

    不妨指定一个方向。

    然后尽量把每个变量用常量表示出来。

    希望自己以后也能想出来。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int N=1e6+5;
    int n;
    ll a[N],base,c[N],ans;
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%lld",&a[i]),base+=a[i];
        base/=n;
        for(int i=1;i<n;i++)c[i]=c[i-1]+a[i]-base;
        sort(c+1,c+n);
        ll x=c[(n+1)>>1];
        for(int i=0;i<n;i++)ans+=abs(x-c[i]);
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    Android官方数据绑定框架DataBinding*
    Application 使用分析*
    Android HandlerThread与IntentService*
    Android中SQLite应用详解*
    Android开发中,那些让您觉得相见恨晚的方法、类或接口*
    巧用ViewPager 打造不一样的广告轮播切换效果*
    Android-Universal-Image-Loader的缓存处理机制与使用 LruCache 缓存图片*
    Android Volley完全解析*
    Android 蓝牙*
    Android自定义View
  • 原文地址:https://www.cnblogs.com/Narh/p/9402191.html
Copyright © 2011-2022 走看看