程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> HDU 4085

HDU 4085

編輯:C++入門知識

斯坦納樹

具體參見國家隊論文

[cpp] 
#include<cstdio> 
#include<cstring> 
#include<queue> 
#define M 1100 
#define N 55 
#define INF 100000000 
using namespace std; 
struct Edge{ 
    int v,w,next; 
}edge[M*2]; 
int head[N],cnt; 
int n,m,k,K; 
int st[N]; 
int dp[N][1100]; 
bool vis[N][1100]; 
int ans[1100]; 
queue<int>q; 
void addedge(int u,int v,int w){ 
    edge[cnt].v=v; 
    edge[cnt].w=w; 
    edge[cnt].next=head[u]; 
    head[u]=cnt++; 
    edge[cnt].v=u; 
    edge[cnt].w=w; 
    edge[cnt].next=head[v]; 
    head[v]=cnt++; 

void init(){ 
    int i,j; 
    K=1<<(2*k); 
    cnt=0; 
    memset(head,-1,sizeof(head)); 
    memset(st,0,sizeof(st)); 
    memset(vis,0,sizeof(vis)); 
    for(i=1;i<=n;i++) 
        for(j=0;j<K;j++) 
            dp[i][j]=INF; 
    for(i=1;i<=k;i++){ 
        st[i]=1<<(i-1); 
        dp[i][st[i]]=0; 
    } 
    for(i=1;i<=k;i++){ 
        st[n-k+i]=1<<(k+i-1); 
        dp[n-k+i][st[n-k+i]]=0; 
    } 

void SPFA(){ 
    int i; 
    while(!q.empty()){ 
        int x=q.front()%10000,y=q.front()/10000; 
        vis[y][x]=0; 
        q.pop(); 
        for(i=head[y];i!=-1;i=edge[i].next){ 
            if(dp[edge[i].v][st[edge[i].v]|x]>dp[y][x]+edge[i].w){ 
                dp[edge[i].v][st[edge[i].v]|x]=dp[y][x]+edge[i].w; 
                if(!vis[edge[i].v][st[edge[i].v]|x] && (st[edge[i].v]|x)==x){ //st[edge[i].v]有可能為0 
                    vis[edge[i].v][st[edge[i].v]|x]=1; 
                    q.push(edge[i].v*10000+x); 
                } 
            } 
        } 
    } 

void Steiner_Tree(){ 
    int i,j,x; 
    for(i=0;i<K;i++){ 
        for(j=1;j<=n;j++){ 
            if(st[j] && (st[j]&i))continue; 
            for(x=(i-1)&i;x;x=(x-1)&i) 
                dp[j][i]=min(dp[j][i],dp[j][x|st[j]]+dp[j][(i-x)|st[j]]); 
            if(dp[j][i]!=INF){ 
                q.push(j*10000+i); 
                vis[j][i]=1; 
            } 
        } 
        SPFA(); 
    } 

bool check(int u){ 
    int r=0,i; 
    for(i=0;i<k;i++){ 
        if(u&(1<<i))r++; 
        if(u&(1<<(i+k)))r--; 
    } 
    return !r; 

int main(){ 
    int t,T,i,j; 
    int u,v,w; 
    scanf("%d",&T); 
    for(t=1;t<=T;t++){ 
        scanf("%d %d %d",&n,&m,&k); 
        init(); 
        for(i=1;i<=m;i++){ 
            scanf("%d %d %d",&u,&v,&w); 
            addedge(u,v,w); 
        } 
        Steiner_Tree(); 
        for(i=0;i<K;i++){ 
            ans[i]=INF; 
            for(j=1;j<=n;j++) 
                ans[i]=min(ans[i],dp[j][i]); 
        } 
        for(i=0;i<K;i++) 
            if(check(i)) 
                for(j=(i-1)&i;j;j=(j-1)&i) 
                    if(check(j)) 
                        ans[i]=min(ans[i],ans[j]+ans[i-j]); 
        if(ans[K-1]==INF)printf("No solution\n"); 
        else printf("%d\n",ans[K-1]); 
    } 
    return 0; 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved