zoukankan      html  css  js  c++  java
  • [JLOI2015]管道连接

    题目传送门

    分析:
    同色点连通挺恶心的
    要求全部点连通的话就可以直接斯坦纳树了
    同色点连通满足还要考虑异色点可能会共用边使答案更小
    于是尝试枚举一个颜色集合的点全部连通,形成斯坦纳树
    然后把所有集合拼起来,形成斯坦纳森林
    之中有一种方案一定是最小的
    枚举子集的子集的子集复杂度是(O(4^n))
    总复杂度为(O(n4^p))
    开O2跑得过还真离谱

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    #include<map>
    
    #define maxn 1005
    #define maxm 6005
    #define INF 0x3f3f3f3f
    
    using namespace std;
    
    inline int getint()
    {
    	int num=0,flag=1;char c;
    	while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
    	while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
    	return num*flag;
    }
    
    int n,K,m;
    int fir[maxn],nxt[maxm],to[maxm],len[maxm],cnt;
    long long f[maxn][1<<10],g[1<<10];
    bool vis[maxn];
    map<int,int>M;
    int cur;
    int c[maxn],id[maxn];
    
    struct node{
    	int u;long long w;
    	friend bool operator <(node x,node y){return x.w>y.w;}
    };
    priority_queue<node>Q;
    
    inline void newnode(int u,int v,int w)
    {to[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt,len[cnt]=w;}
    inline void dij(int S)
    {
    	memset(vis,0,sizeof vis);
    	while(!Q.empty())
    	{
    		int u=Q.top().u;Q.pop();
    		if(vis[u])continue;vis[u]=1;
    		for(int i=fir[u];i;i=nxt[i])
    			if(f[to[i]][S]>f[u][S]+len[i])
    				Q.push((node){to[i],f[to[i]][S]=f[u][S]+len[i]});
    	}
    }
    
    inline long long solve(int t)
    {
    	for(int i=0;i<(1<<t);i++)
    	{
    		for(int k=1;k<=n;k++)
    		{
    			for(int j=i&(i-1);j;j=i&(j-1))
    				f[k][i]=min(f[k][i],f[k][j]+f[k][i^j]);
    			if(f[k][i]!=f[0][0])Q.push((node){k,f[k][i]});
    		}
    		dij(i);
    	}
    	long long ans=1ll<<60;
    	for(int i=1;i<=n;i++)ans=min(ans,f[i][(1<<t)-1]);
    	return ans;
    }
    
    int main()
    {
    	n=getint(),m=getint(),K=getint();
    	memset(f,INF,sizeof f);
    	for(int i=1;i<=m;i++)
    	{
    		int u=getint(),v=getint(),w=getint();
    		newnode(u,v,w),newnode(v,u,w);
    	}
    	for(int i=1;i<=K;i++)
    	{
    		c[i]=getint(),id[i]=getint();
    		if(!M[c[i]])M[c[i]]=++cur;
    		c[i]=M[c[i]];
    	}
    	memset(g,INF,sizeof g);
    	for(int i=1;i<(1<<cur);i++)
    	{
    		int tmp=0;
    		memset(f,INF,sizeof f);
    		for(int j=1;j<=K;j++)if(i&(1<<(c[j]-1)))f[id[j]][1<<tmp]=0,tmp++;
    		g[i]=solve(tmp);
    	}
    	for(int i=1;i<(1<<cur);i++)for(int j=i&(i-1);j;j=i&(j-1))
    		g[i]=min(g[i],g[j]+g[i^j]);
    	printf("%lld
    ",g[(1<<cur)-1]);
    }
    

  • 相关阅读:
    实现一个与内容合二为一的ActionBar动画效果
    hdoj 1506&amp;&amp;1505(City Game) dp
    remine chart2安装
    zoom的学习
    海哥:T2C时代的到来了,那么什么叫T2C?
    minhash算法
    动态创建按钮的JS
    socket编程在windows和linux下的区别
    http staus汇总
    MySQL HINT:Straight_JOIN
  • 原文地址:https://www.cnblogs.com/Darknesses/p/13089702.html
Copyright © 2011-2022 走看看