• BZOJ 4006: [JLOI2015]管道连接


    斯坦纳树+子集DP

    spfa 9272ms

    Dijkstra 13016ms

    luogu Dijkstra 直接TLE

    综上所述斯坦纳树直接spfa

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int Num,cnt,n,m,p,F[1005][2005],stack[1000005],instack[1005],last[1005],sta[15],cost[2005],G[2005],c[15];
    struct node1{
    	int c,id;
    }q[15];
    struct node{
    	int to,next,val;
    }e[6005];
    void add(int a,int b,int c){
    	e[++cnt].to=b;
    	e[cnt].next=last[a];
    	e[cnt].val=c;
    	last[a]=cnt;
    }
    void dfs(int t,int x,int y){
    	if (t>Num){
    		G[x]=cost[y];
    		return;
    	}
    	dfs(t+1,x<<1,y);
    	dfs(t+1,x<<1|1,y|sta[t]);
    }
    int main(){
    	scanf("%d%d%d",&n,&m,&p);
    	for (int i=1; i<=m; i++){
    		int x,y,z;
    		scanf("%d%d%d",&x,&y,&z);
    		add(x,y,z);
    		add(y,x,z);
    	}
    	for (int i=0; i<p; i++) scanf("%d%d",&q[i].c,&q[i].id);
    	for (int st=1; st<=n; st++)
    		for (int i=0; i<(1<<p); i++)
    			F[st][i]=1e9;
    	for (int i=0; i<p; i++) F[q[i].id][1<<i]=0;
    	for (int i=1; i<=n; i++) F[i][0]=0;
    	for (int i=0; i<(1<<p); i++){
    		for (int st=1; st<=n; st++)
    			for (int j=i; j; j=(j-1)&i)
    				F[st][i]=min(F[st][i],F[st][j]+F[st][i^j]);
    		int head=0,tail=0;
    		for (int st=1; st<=n; st++) stack[++tail]=st;
    		for (int st=1; st<=n; st++) instack[st]=1;
    		while (head<tail){
    			int x=stack[++head];
    			instack[x]=0;
    			for (int I=last[x]; I; I=e[I].next){
    				int V=e[I].to;
    				if (F[V][i]>F[x][i]+e[I].val){
    					F[V][i]=F[x][i]+e[I].val;
    					if (!instack[V]){
    						instack[V]=1;
    						stack[++tail]=V;
    					}
    				}
    			}
    
    		}
    	}
    	for (int i=0; i<(1<<p); i++) cost[i]=1e9;
    	for (int i=0; i<(1<<p); i++)
    		for (int st=1; st<=n; st++)
    			cost[i]=min(cost[i],F[st][i]);
    	for (int i=1; i<=p; i++) c[i]=q[i-1].c;
    	sort(c+1,c+p+1);
    	Num=unique(c+1,c+p+1)-c-1;
    	for (int i=0; i<p; i++) q[i].c=lower_bound(c+1,c+Num+1,q[i].c)-c;
    	for (int i=0; i<p; i++)	sta[q[i].c]|=(1<<i);
    	for (int i=0; i<(1<<Num); i++) G[i]=1e9;
    	dfs(1,0,0);
    	for (int i=0; i<(1<<Num); i++)
    		for (int j=i; j; j=(j-1)&i)
    			G[i]=min(G[i],G[j]+G[i^j]);
    	printf("%d
    ",G[(1<<Num)-1]);
    	return 0;
    }
    

      

  • 相关阅读:
    根据dateFormatter创建NSDate类型数据
    centos6.5下oracle自动备份删除指定天数的文件
    svg-edit和svg中的自定义属性
    vc读取当前路径和读取配置ini文件
    powerdesiner技巧
    oracle理解和导入导出
    highstock无图像
    winform中datagridview刷新后的排序记忆
    freemarker取数
    winform clickonce在线安装
  • 原文地址:https://www.cnblogs.com/silenty/p/9927651.html
Copyright © 2020-2023  润新知