zoukankan      html  css  js  c++  java
  • HDU 4085 Steiner树

    主题链接:http://acm.hdu.edu.cn/showproblem.php?

    pid=4085

    由于这题专门花一晚上学习斯坦纳树。找到比較好的学习资料,链接在这里:http://endlesscount.blog.163.com/blog/static/821197872012525113427573/

    花了非常长时间照着别人写了一份自己风格的代码,慢慢理解:

    /* ***********************************************
    Author :rabbit
    Created Time :2014/7/16 20:45:31
    File Name :1.cpp
    ************************************************ */
    #pragma comment(linker, "/STACK:102400000,102400000")
    #include <stdio.h>
    #include <iostream>
    #include <algorithm>
    #include <sstream>
    #include <stdlib.h>
    #include <string.h>
    #include <limits.h>
    #include <string>
    #include <time.h>
    #include <math.h>
    #include <queue>
    #include <stack>
    #include <set>
    #include <map>
    using namespace std;
    #define INF 100000000
    #define eps 1e-8
    #define pi acos(-1.0)
    typedef long long ll;
    const int maxn=60;
    struct Edge{
    	int next,to,val;
    }edge[2100];
    int head[maxn],tol,n,m,K;
    int s[maxn],in[maxn][1<<10],d[maxn][1<<10],dp[1<<10];
    void addedge(int u,int v,int c){
    	edge[tol].to=v;
    	edge[tol].next=head[u];
    	edge[tol].val=c;
    	head[u]=tol++;
    }
    bool check(int x){
    	int r=0;
    	for(int i=0;x;i++,x>>=1)
    		r+=(x&1)*(i<K?

    1:-1); return r==0; } int main() { //freopen("data.in","r",stdin); //freopen("data.out","w",stdout); int T; cin>>T; while(T--){ memset(head,-1,sizeof(head));tol=0; memset(in,0,sizeof(in)); memset(s,0,sizeof(s)); scanf("%d%d%d",&n,&m,&K); int nn=1<<(2*K); for(int i=1;i<=n;i++) for(int j=0;j<nn;j++) d[i][j]=INF; while(m--){ int u,v,w; scanf("%d%d%d",&u,&v,&w); addedge(u,v,w); addedge(v,u,w); } for(int i=1;i<=K;i++){ s[i]=1<<(i-1),d[i][s[i]]=0; s[n-i+1]=1<<(K+i-1),d[n-i+1][s[n-i+1]]=0; } for(int y=0;y<nn;y++){ queue<int> Q; for(int x=1;x<=n;x++){ for(int i=(y-1)&y;i;i=(i-1)&y) d[x][y]=min(d[x][y],d[x][i|s[x]]+d[x][(y-i)|s[x]]); if(d[x][y]<INF)Q.push(x*10000+y),in[x][y]=1; } while(!Q.empty()){ int x=Q.front()/10000,y=Q.front()%10000; in[x][y]=0; Q.pop(); for(int i=head[x];i!=-1;i=edge[i].next){ int v=edge[i].to; if(d[v][y|s[v]]>d[x][y]+edge[i].val){ d[v][y|s[v]]=d[x][y]+edge[i].val; if(y==(y|s[v])&&!in[v][y]){ in[v][y]=1; Q.push(10000*v+y); } } } } } for(int j=0;j<nn;j++){ dp[j]=INF; for(int i=1;i<=n;i++) dp[j]=min(dp[j],d[i][j]); } for(int i=1;i<nn;i++) if(check(i)) for(int j=i&(i-1);j;j=(j-1)&i) if(check(j)) dp[i]=min(dp[i],dp[j]+dp[i-j]); if(dp[nn-1]>=INF)puts("No solution"); else printf("%d ",dp[nn-1]); } return 0; }



    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    组合数学
    组合数学
    组合数学
    组合数学 + STL --- 利用STL生成全排列
    组合数学
    数论
    给xcode项目重命名
    iOS中动态注入JavaScript方法。动态给html标签添加事件
    swift
    swift
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4625504.html
Copyright © 2011-2022 走看看