• Gym


    https://cn.vjudge.net/problem/Gym-101492I

    如果用单个点代表每个区间 利用拆点来限制区间的流量的话 点是 n^2/2+m个 边是2*n^2条

    但是这样会T

    解法1:单纯形

    单纯形套板可以过

    #include <bits/stdc++.h>
    #define N
    using namespace std;
    
    typedef unsigned ui;
    typedef long double dbl;
    
    const dbl eps = 1e-8;
    
    ui n, m, c[5001]; dbl a[4001][201], x[201], z;
    
    int dcmp(dbl d) { return d < -eps ? -1 : d <= eps ? 0 : 1; }
    
    //    u in, v out
    void pivot(ui u, ui v) {
        swap(c[n + u], c[v]);
        //    row u *= 1 / a[u][v]
        dbl k = a[u][v]; a[u][v] = 1;
        for (ui j = 0; j <= n; ++j) a[u][j] /= k;
        for (ui i = 0; i <= m; ++i) {
            if (i == u || !dcmp(a[i][v])) continue;
            k = a[i][v]; a[i][v] = 0;
            for (ui j = 0; j <= n; ++j)
                a[i][j] -= a[u][j] * k;
        }
    }
    
    bool init() {
        for (ui i = 1; i <= n; ++i) c[i] = i;
        while (1) {
            ui u = 0, v = 0;
            for (ui i = 1; i <= m; ++i)
                if (dcmp(a[i][0]) == -1 && (!u || dcmp(a[u][0] - a[i][0]) == 1)) u = i;
            if (!u) return 1;
            for (ui j = 1; j <= n && !v; ++j)
                if (dcmp(a[u][j]) == -1) v = j;
            if (!v) return 0;
            pivot(u, v);
        }
    }
    
    int simplex() {
        if (!init()) return 0;
        else while (1) {
            ui u = 0, v = 0;
            for (ui j = 1; j <= n; ++j)
                if (dcmp(a[0][j]) == 1 && (!v || a[0][j] > a[0][v])) v = j;
    
            if (!v) {
                z = -a[0][0];
                for (ui i = 1; i <= m; ++i)
                    x[c[n + i]] = a[i][0];
                return 1;
            }
    
            dbl w = 1e20;
            for (ui i = 1; i <= m; ++i)
                if (dcmp(a[i][v]) == 1 &&
                    dcmp(w - a[i][0] / a[i][v]) == 1) {
                    w = a[i][0] / a[i][v];
                    u = i;
                }
            if (!u) return 2;
            pivot(u, v);
        }
    }
    
    
    int main(void) {
        ios::sync_with_stdio(0); cin.tie(0);
    #ifndef ONLINE_JUDGE
        ifstream cin("1.in");
    #endif
        ui t;
        cin >> n >> m;
        for (ui j = 1; j <= n; ++j) cin >> a[0][j];
        for (ui i = 1; i <= m; ++i) {
            int l, r; cin >> l >> r;
            for (int j = l; j <= r; ++j)
                a[i][j] = 1;
            cin >> a[i][0];
        }
    
        int res = simplex();
        if (res == 0) cout << "Infeasible" << endl;
        else if (res == 2) cout << "Unbounded" << endl;
        else {
            cout << (long long)z << endl;
        }
        return 0;
    }
    View Code

    解法2:网络流

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<string.h>
    #include<string>
    #include<stdlib.h>
    #define inf 0x3f3f3f3f
    typedef long long ll;
    using namespace std;
    const int maxn=300;
    const int maxm=10005;
    struct node
    {
        int t,f,c,next;
    }e[maxm*2];
    int a[maxn];
    int head[maxn],dis[maxn],vis[maxn];
    int pre[maxn];
    int cnt,s,t;
    void add(int s,int t,int c,int f)
    {
        e[cnt].t=t;
        e[cnt].c=c;
        e[cnt].f=f;
        e[cnt].next=head[s];
        head[s]=cnt++;
        e[cnt].t=s;
        e[cnt].c=0;
        e[cnt].f=-f;
        e[cnt].next=head[t];
        head[t]=cnt++;
    }
    void intt()
    {
        cnt=0;
        s=0;t=250;
        memset(head,-1,sizeof(head));
    }
    int spfa()
    {
        queue<int >que;
        for(int i=0;i<maxn;i++)
        {
            dis[i]=inf;
            vis[i]=0;
            pre[i]=-1;
        }
        dis[s]=0;
        vis[s]=1;
        que.push(s);
        while(que.size())
        {
            int u=que.front();
            que.pop();
            vis[u]=0;
            for(int i=head[u];i!=-1;i=e[i].next)
            {
                int v=e[i].t;
                if(e[i].c>0&&dis[u]+e[i].f<dis[v])
                {
                    dis[v]=dis[u]+e[i].f;
                    pre[v]=i;
                    if(vis[v]==0)
                    {
                        vis[v]=1;
                        que.push(v);
                    }
                }
            }
        }
        if(pre[t]==-1)return 0;
        return 1;
    }
    ll mincost()
    {
        int flow=0;
        ll cost=0;
        while(spfa())
        {
          int tf=inf;
          for(int i=pre[t];i!=-1;i=pre[e[i^1].t])
                tf=min(e[i].c,tf);
          flow+=tf;
          for(int i=pre[t];i!=-1;i=pre[e[i^1].t])
          {
              e[i].c-=tf;
              e[i^1].c+=tf;
              cost+=1ll*e[i].f*tf;
          }
        }
        return cost;
    }
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        memset(a,0,sizeof(a));
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        intt();
        for(int i=1;i<=m;i++)
        {
            int u,v,k;
            scanf("%d%d%d",&u,&v,&k);
            add(u,v+1,inf,k);
        }
        for(int i=n+1;i>=2;i--)
            add(i,i-1,inf,0);
        for(int i=n+1;i>=1;i--)
            {
                int temp=a[i]-a[i-1];
                if(temp<0)
                {
                    add(i,t,-temp,0);
                }
                else add(s,i,temp,0);
            }
        printf("%lld
    ",mincost());
    }
    View Code

    转载自https://blog.csdn.net/dhydye/article/details/80515359 不懂原理QAQ

  • 相关阅读:
    codeforces——模拟
    线段树水题
    编码格式分类: 前后端传递数据的编码格式contentType
    爬虫之爬取求职小网站
    auth 模块使用篇
    后端获取前端的多个数据用getlist
    字符串值的替换
    单例的5种开启方式
    forms 组件的功能和使用
    cookie和session 的初步介绍
  • 原文地址:https://www.cnblogs.com/Aragaki/p/11191287.html
Copyright © 2020-2023  润新知