zoukankan      html  css  js  c++  java
  • bzoj3118: Orz the MST(线性规划+单纯形法)

    传送门

    不难发现,对于每一条树边肯定要减小它的权值,对于每一条非树边要增加它的权值

    对于每一条非树边(j),他肯定与某些树边构成了一个环,那么它的边权必须大于等于这个环上的所有边

    设其中一条边为(i),变化量为(x),那么就要满足(w_i-x_ileq w_j+x_j),即(x_i+x_jgeq 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
    ",-a[0][0]);return 0;
    }
    
  • 相关阅读:
    拦截器实现对用户是否登录及登陆超时的验证
    Spring+Websocket实现消息的推送
    经典 socket通讯 -- 已验证
    Unity编辑器扩展之RequireComponent等详解
    如何理解着色器,渲染管线,光栅化等概念?
    Unity3D研究院编辑器之脚本设置ToolBar及脚本设置顶视图
    Unity3D研究院编辑器之重写Hierarchy的右键菜单
    Unity3D研究院编辑器之自定义默认资源的Inspector面板
    Unity3D研究院之拓展系统自带组件的Inspector视图
    Unity3D研究院之Inspector视图中的get/set使用
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/10104370.html
Copyright © 2011-2022 走看看