BZOJ1061: [Noi2008]志愿者招募 线性规划之--构造初始可行解
BZOJ4184: shallot

BZOJ3118: Orz the MST

shinbokuow posted @ Aug 21, 2015 06:17:53 PM in BZOJ with tags 线性规划 单纯形 , 1143 阅读

 

题解:

首先树上的边权只可能减少.非树边上的权值只可能增大.

然后就有对于一条非树边,修改后的权值要不小于所有它覆盖的树边被修改后的权值.

注意题目中其实是保证树边数目$\times$非树边数目$\leq{4000}$的.

然后对偶一下发现有初始可行解,直接上单纯形.

代码:

#include<cstdio>
#include<cctype>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
 
#define inf 0x3f3f3f3f
struct Linear_Programming{
    static const int N=4010;
    static const int M=1010;
    int n,m,A[M][N],b[M],c[N],v,B[M],nB[N];
    int _c[N],_v,_nB[N],Bins[N+M],nBins[N+M];
    inline void pivot(int l,int e){
        int i,j;
        for(i=1;i<=n;++i)
            if(i!=e)
                A[l][i]/=A[l][e];
        b[l]/=A[l][e];
        A[l][e]=1/A[l][e];
        for(i=1;i<=m;++i)
            if(i!=l&&A[i][e]!=0){
                for(j=1;j<=n;++j)
                    if(j!=e)
                        A[i][j]-=A[i][e]*A[l][j];
                b[i]-=A[i][e]*b[l];
                A[i][e]*=-A[l][e];
            }
        for(i=1;i<=n;++i)
            if(i!=e)
                c[i]-=c[e]*A[l][i];
        v+=c[e]*b[l];
        c[e]*=-A[l][e];
        swap(B[l],nB[e]);
    }
    inline int Simplex(){
        int i,j,l,e,lim;
        while(1){
            for(e=0,i=1;i<=n;++i)
                if(c[i]>0){
                    e=i;
                    break;
                }
            if(!e)
                return v;
            for(lim=inf,i=1;i<=m;++i)
                if(A[i][e]>0&&lim>b[i]/A[i][e]){
                    l=i;
                    lim=b[i]/A[i][e];
                }
            if(lim==inf)
                return inf;
            pivot(l,e);
        }
    }
    inline bool init(){
        int i,j,l,e,min_b=inf;
        for(i=1;i<=m;++i)
            if(b[i]<min_b){
                min_b=b[i];
                l=i;
            }
        if(min_b>=0)
            return 1;
        memcpy(_c,c,sizeof c);
        _v=v;
        memcpy(_nB,nB,sizeof nB);
        memset(c,0,sizeof c);
        v=0;
        nB[++n]=0;
        c[n]=-1;
        for(i=1;i<=m;++i)
            A[i][n]=-1;
        pivot(l,n);
        if(Simplex()<0)
            return 0;
        else{
            for(i=1;i<=m;++i)
                if(B[i]==0){
                    for(j=1;j<=n;++j)
                        if(A[i][j]!=0){
                            pivot(i,j);
                            break;
                        }
                }
            for(i=1;i<=n;++i)
                if(nB[i]==0)
                    e=i;
            --n;
            for(i=e;i<=n;++i)
                nB[i]=nB[i+1];
            for(i=1;i<=m;++i)
                for(j=e;j<=n;++j)
                    A[i][j]=A[i][j+1];
            memset(c,0,sizeof c);
            v=_v;
            for(i=1;i<=n;++i)
                nBins[nB[i]]=i;
            for(i=1;i<=m;++i)
                Bins[B[i]]=i;
            for(i=1;i<=n;++i)
                if(nBins[_nB[i]])
                    c[nBins[_nB[i]]]+=_c[i];
                else{
                    v+=_c[i]*b[Bins[_nB[i]]];
                    for(j=1;j<=n;++j)
                        c[j]-=_c[i]*A[Bins[_nB[i]]][j];
                }
            return 1;
        }
    }
}g;
 
#define N 310
#define M 1010
int head[N],next[M<<1],end[M<<1],F[M<<1],ind=2;
inline void addedge(int a,int b,int f){
    int q=ind++;
    end[q]=b;
    next[q]=head[a];
    head[a]=q;
    F[q]=f;
}
inline void make(int a,int b,int f){
    addedge(a,b,f);
    addedge(b,a,f);
}
 
struct Edge{
    int a,b,c,f,A,B;
    inline void read(){
        scanf("%d%d%d%d%d%d",&a,&b,&c,&f,&A,&B);
    }
}E[M];
 
int pa[N],pa_edge[N];
inline void dfs(int x,int fa){
    for(int j=head[x];j;j=next[j])
        if(end[j]!=fa&&F[j]){
            pa[end[j]]=x;
            pa_edge[end[j]]=j>>1;
            dfs(end[j],x);
        }
}
 
int main(){
#ifndef ONLINE_JUDGE
    freopen("tt.in","r",stdin);
#endif
 
    int n,m;
    scanf("%d%d",&n,&m);
    int i,j;
    for(i=1;i<=m;++i)
        E[i].read();
    for(i=1;i<=m;++i)
        make(E[i].a,E[i].b,E[i].f);
    int lim=0;
    for(i=1;i<=m;++i)
        if(!E[i].f){
            pa[E[i].a]=0;
            dfs(E[i].a,-1);
            for(j=E[i].b;j!=E[i].a;j=pa[j]){
                ++lim;
                g.A[pa_edge[j]][lim]=1;
                g.A[i][lim]=1;
                g.c[lim]=E[pa_edge[j]].c-E[i].c;
            }
        }
    for(i=1;i<=m;++i)
        g.b[i]=E[i].f?E[i].B:E[i].A;
    g.n=lim;
    g.m=m;
    for(i=1;i<=g.n;++i)
        g.nB[i]=i;
    for(i=1;i<=g.m;++i)
        g.B[i]=g.n+i;
    g.init();
    cout<<g.Simplex()<<endl;
    return 0;
}
charlly 说:
Oct 05, 2022 11:52:37 AM

This is the best forum that you can rely on to get details related to different programs. It will be really easy for you to find programs Hemp Oil Benefits here and I think it is so good for you to be a part of it.


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter