zoukankan      html  css  js  c++  java
  • CF375E Red and Black Tree(线性规划)

    CF375E Red and Black Tree(线性规划)

    Luogu

    题解时间

    很明显有一个略显复杂的 $ n^3 $ dp,但不在今天讨论范围内。

    考虑一些更简单的方法。

    设有 $ m $ 个点为黑,转化成线性规划问题,很明显有

    [minimum:sumlimits_{i} ( 1 - col_{i} ) x_{i} ]

    [sumlimits_{ dis(i,j) le lim } x_{j} ge 1 ]

    [sumlimits_{i} x_{i} =m ]

    最后的一个等式转化成两个不等式,之后将整个线性规划利用对偶原理转化成标准型直接单纯形法求解即可。

    毫无疑问最终结果不会有 $ x_{i} > 1 $ ,而对于是否可能出现小数,很明显不会影响最终结果。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long lint;
    struct pat{int x,y;pat(int x=0,int y=0):x(x),y(y){}bool operator<(const pat &p)const{return x==p.x?y<p.y:x<p.x;}};
    template<typename TP>inline void read(TP &tar)
    {
    	TP ret=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){ret=ret*10+(ch-'0');ch=getchar();}
    	tar=ret*f;
    }
    template<typename TP,typename... Args>inline void read(TP& t,Args&... args){read(t),read(args...);}
    namespace RKK
    {
    const int N=511;
    const double eps=1e-8,inf=1e18;int cz(const double &a){return fabs(a)<=eps?0:(a>eps?1:-1);}
    struct sumireko{int to,ne,w;}e[N<<1];int he[N],ecnt;
    void addline(int f,int t,int w){e[++ecnt].to=t,e[ecnt].w=w,e[ecnt].ne=he[f],he[f]=ecnt;}
    namespace lisp
    {
    	int n,m,id[N<<1];double a[N][N];
    	void pivot(int l,int e)
    	{
    		swap(id[m+l],id[e]);
    		double k=-a[l][e];a[l][e]=-1;
    		for(int j=0;j<=m;j++) a[l][j]/=k;
    		for(int i=0;i<=n;i++)if(i!=l&&cz(a[i][e]))
    		{
    			k=a[i][e],a[i][e]=0;
    			for(int j=0;j<=m;j++) a[i][j]+=k*a[l][j];
    		}
    	}
    	int init()
    	{
    		for(int i=1;i<=m+n;i++) id[i]=i;
    		while(1)
    		{
    			int l=0,e=0;
    			for(int i=1;i<=n;i++)if(cz(a[i][0])<0&&(!l||rand()&1)) l=i;
    			if(!l) break;
    			for(int j=1;j<=m;j++)if(cz(a[l][j])>0&&(!e||rand()&1)) e=j;
    			if(!e) return -1;//no solution
    			pivot(l,e);
    		}return 0;
    	}
    	int simplex()
    	{
    		while(1)
    		{
    			int l=0,e=0;double mi=inf;
    			for(int j=1;j<=m;j++)if(cz(a[0][j])>0&&(!e||rand()&1)) e=j;
    			if(!e) break;
    			for(int i=1;i<=n;i++)if(cz(a[i][e])<0&&(!l||-a[i][0]/a[i][e]<mi)) l=i,mi=-a[i][0]/a[i][e];
    			if(!l) return -1;//unbounded
    			pivot(l,e);
    		}return 0;
    	}
    	void work()
    	{
    		if(init()==-1) return (void)(puts("-1"));
    		if(simplex()==-1) return (void)(puts("-1"));
    		printf("%.0lf
    ",a[0][0]);
    	}
    }
    int n,m,lim,col[N];
    void dfs(int x,int f,int sp,int dis)
    {
    	if(dis>lim) return;
    	lisp::a[x][sp]=-1;
    	for(int i=he[x],t=e[i].to;i;i=e[i].ne,t=e[i].to)if(t!=f) dfs(t,x,sp,dis+e[i].w);
    }
    int main()
    {
    	read(n,lim);for(int i=1;i<=n;i++) read(col[i]),m+=col[i];
    	for(int i=2,x,y,w;i<=n;i++) read(x,y,w),addline(x,y,w),addline(y,x,w);
    	lisp::n=n,lisp::m=n+2;
    	for(int i=1;i<=n;i++) lisp::a[i][0]=!col[i],lisp::a[0][i]=1;lisp::a[0][n+1]=m,lisp::a[0][n+2]=-m;
    	for(int i=1;i<=n;i++) lisp::a[i][n+1]=-1,lisp::a[i][n+2]=1;
    	for(int i=1;i<=n;i++) dfs(i,0,i,0);
    	lisp::work();
    	return 0;
    }
    }
    int main(){return RKK::main();}
    
  • 相关阅读:
    4-MSP430定时器_定时器中断
    关于STM32的外部引脚中断的问题
    关于stm32的正交解码
    红外接收控制灯亮灭
    mack pro常用快捷键
    liunx操作系统安装<一>
    支付宝架构师:从工程师到架构师的成长之路
    maven之setting.xml的配置详解
    分布式之《保证分布式系统数据一致性的6种解决方案》
    Eclipse中jsp、js文件编辑时,卡死现象解决汇总
  • 原文地址:https://www.cnblogs.com/rikurika/p/13298622.html
Copyright © 2011-2022 走看看