zoukankan      html  css  js  c++  java
  • 最小树形图简单总结

    [BZOJ4349]最小树形图&[BZOJ2260]商店购物

    分析?

    做法都是先通过最优方案每种选一个,这样最后的答案一定最优。每种选一个的最优方案可以用最小树形图求。

    不要忘记写if(e[i].frm!=e[i].to)

    第二个题坑点超多,有(M_i=0)的情况,据说还有自环。

    代码

    #include <bits/stdc++.h>
    #define rin(i,a,b) for(register int i=(a);i<=(b);++i)
    #define irin(i,a,b) for(register int i=(a);i>=(b);--i)
    #define trav(i,a) for(register int i=head[a];i;i=e[i].nxt)
    typedef long long LL;
    using std::cin;
    using std::cout;
    using std::endl;
    
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    	while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
    	return x*f;
    }
    
    inline double readd(){
    	double x;scanf("%lf",&x);return x;
    }
    
    const int MAXN=55;
    const double eps=1e-8;
    int n,m,s,ecnt,head[MAXN],b[MAXN],id[MAXN];
    int	pre[MAXN],vis[MAXN],blg[MAXN];
    double a[MAXN],minw[MAXN],ans;
    bool ban[MAXN];
    struct Edge{int frm,to,nxt;double w;}e[MAXN*MAXN+MAXN];
    
    inline void add_edge(int bg,int ed,double val){
    	ecnt++;e[ecnt].frm=bg;e[ecnt].to=ed;e[ecnt].nxt=head[bg];e[ecnt].w=val;head[bg]=ecnt;
    }
    
    void zhuliu(){
    	while(1){
    		memset(minw,0x43,sizeof minw);memset(pre,0,sizeof pre);memset(vis,0,sizeof vis);memset(blg,0,sizeof blg);
    		rin(i,1,ecnt) if(e[i].frm!=e[i].to) if(e[i].w<minw[e[i].to]) minw[e[i].to]=e[i].w,pre[e[i].to]=e[i].frm;
    		bool flag=false;
    		minw[s]=0,pre[s]=0;
    		rin(i,1,s) if(!ban[i]){
    			ans+=minw[i];int now=i;
    			while(now&&!vis[now]) vis[now]=i,now=pre[now];
    			if(vis[now]==i){
    				flag=true;blg[now]=now;int temp=now;now=pre[now];
    				while(now!=temp) blg[now]=temp,now=pre[now];
    			}
    		}
    		if(!flag) return;
    		rin(i,1,s) if(!ban[i]&&!blg[i]) blg[i]=i; else if(!ban[i]&&blg[i]!=i) ban[i]=true;
    		rin(i,1,ecnt) if(e[i].frm!=e[i].to) e[i].w-=minw[e[i].to],e[i].frm=blg[e[i].frm],e[i].to=blg[e[i].to];
    	}
    }
    
    int main(){
    	n=read();int temp=0;
    	rin(i,1,n){
    		a[i]=readd(),b[i]=read(),++temp;
    		if(!b[i]){n--,i--;continue;}id[temp]=i;
    	}
    	s=n+1;
    	rin(i,1,n) add_edge(s,i,a[i]);
    	m=read();
    	rin(i,1,m){
    		int x=id[read()],y=id[read()];double z=readd();
    		if(!x||!y) continue;if(x!=y) add_edge(x,y,z);a[y]=std::min(a[y],z);
    	}
    	zhuliu();
    	rin(i,1,n) ans+=(b[i]-1)*a[i];
    	printf("%.2f
    ",ans+eps);
    	return 0;
    }
    
  • 相关阅读:
    为何没有.aspx.designer.cs文件?
    ItemDataBound的用法
    DataList控件 属性全攻略
    给LinkButton添加href、target属性
    给文本框添加灰色提示文字
    转载::深入研究DataList分页方法
    WCF 第六章 序列化与编码 保留引用和循环引用
    WCF 第六章 序列化和编码之NetDataContractSerializer
    WCF 第六章 序列化与编码 比较WCF序列化选项
    WCF 第六章 序列化和编码 使用代理序列化类型
  • 原文地址:https://www.cnblogs.com/ErkkiErkko/p/10286193.html
Copyright © 2011-2022 走看看