1. 程式人生 > >bzoj3118: Orz the MST(線性規劃+單純形法)

bzoj3118: Orz the MST(線性規劃+單純形法)

傳送門

不難發現,對於每一條樹邊肯定要減小它的權值,對於每一條非樹邊要增加它的權值

對於每一條非樹邊\(j\),他肯定與某些樹邊構成了一個環,那麼它的邊權必須大於等於這個環上的所有邊

設其中一條邊為\(i\),變化量為\(x\),那麼就要滿足\(w_i-x_i\leq w_j+x_j\),即\(x_i+x_j\geq w_i-w_j\)

然後這就是個線性規劃了。因為這線性規劃的目標函式要取最小,所以我們把它對偶一下就可以了

//minamoto
#include<bits/stdc++.h>
#define R register
#define Loli true
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
    R int res,f=1;R char ch;
    while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
    for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
    return res*f;
}
const int N=1005,M=10005;const double eps=1e-8,inf=1e18;
struct eg{int v,nx,id;}e[N<<1];int head[N],tot;
inline void add(R int u,R int v,R int id){e[++tot]={v,head[u],id},head[u]=tot;}
int n,m,nn,mm,u,v,x,dep[N],fa[N],id[N],U[N],V[N],W[N],F[N],A[N],B[N];
double a[N][M];
void dfs(int u){go(u)if(v!=fa[u])fa[v]=u,id[v]=e[i].id,dep[v]=dep[u]+1,dfs(v);}
void pivot(int l,int e){
    double t=a[l][e];a[l][e]=1;fp(i,0,m)a[l][i]/=t;
    fp(i,0,n)if(i!=l&&fabs(a[i][e])>eps){
        t=a[i][e],a[i][e]=0;
        fp(j,0,m)a[i][j]-=t*a[l][j];
    }
}
void simplex(){
    while(Loli){
        int l=0,e=0;double mn=inf;
        fp(i,1,m)if(a[0][i]>eps){e=i;break;}if(!e)return;
        fp(i,1,n)if(a[i][e]>eps&&a[i][0]/a[i][e]<mn)mn=a[i][0]/a[i][e],l=i;
        pivot(l,e);
    }
}
int main(){
//  freopen("testdata.in","r",stdin);
    nn=read(),mm=read();
    fp(i,1,mm){
        U[i]=read(),V[i]=read(),W[i]=read(),F[i]=read(),A[i]=read(),B[i]=read();
        if(F[i])add(U[i],V[i],i),add(V[i],U[i],i);
    }dfs(1),n=mm;
    fp(i,1,mm)if(F[i])a[i][0]=B[i];
    else{
        a[i][0]=A[i],u=U[i],v=V[i];
        while(u!=v){
            if(dep[u]<dep[v])swap(u,v);
            x=id[u];if(W[x]>W[i])++m,a[x][m]=a[i][m]=1,a[0][m]=W[x]-W[i];
            u=fa[u];
        }
    }simplex();printf("%.0lf\n",-a[0][0]);return 0;
}