Clover wand-like pressure kruskal + DP

Clover Wand


Question:
Wand Custodian \ (Freda \) combines four weapons, so the top of the wand slowly give birth to a four-leaf clover, four leaves hair with a touch of magic seven-color light. Sword law enforcement \ (Rainbow \) remove a disc, set with gems N on the disk, number \ (0 \ N-SIM. 1 \) . Energy is the i-th gems \ (Ai \) . If \ (Ai> 0 \) , represents gem high energy required to \ (Ai \) of energy to other gemstones; if \ (Ai <0 \) , gem represents the energy is too low, it is necessary acquired from other precious stones at \ (- Ai \) energy. Ensure \ (\ SUM Ai \) \ (= 0 \) . Only when all the gems of the energy being equal, the Clover wand is inserted into the center of the disk, in order to open channels supernatural world.
However, only \ (M \) between stones can pass each other energy, where the first \ (i \) between gems no matter how much energy transfer, must spend (Ti \) \ price. Expedition members who want to know how much the cost of a minimum of energy it takes to make all the gems are the same?

Solution
We note that this question \ (Ai \) the sum of \ (0 \) draw a figure shows an edge at most once passed in order to minimize the cost should be deleted and the right side so that it is \ (0 \) connected graph the minimum value of edge weights
answer by one of a weight and \ (0 \) communicating FIG composition and \ (n-\) is small
so thought \ (Kruskal \) and a compressed state \ (the DP \)
code:

#include<bits/stdc++.h>  
using namespace std;  
#define maxnn 66666  
#define inf 10000000 
int f[maxnn];  
int dp[maxnn]; 
int a[maxnn];  
int cnt=0; 
int all=0;  struct node  
{  
    int st,en,w;  
}e[maxnn];  

int n, m; 
int sum[maxnn];
bool cmp(node a ,node b) 
{ 
        return a.w<b.w; 
} 
int gf(int v) 
{ 
    return f[v]==v?v:f[v]=gf(f[v]); 
} 
int krus(int v,int num) 
{ 
    int www=0; 
            for(int i=1;i<=n;i++) 
            { 
                f[i]=i; 
            } 
            for(int i=1;i<=cnt;i++) 
            { 
                    if(((1<<e[i].st-1)&v)&&((1<<e[i].en-1)&v)) 
                    { 
                        if(gf(e[i].st)!=gf(e[i].en)) 
                        { 
                            num--; 
                            int fx=gf(e[i].st); 
                            f[fx]=gf(e[i].en); 
                            www+=e[i].w; 
                        } 
                    } 
            } 
            int ans=0; 
            if(num==1) return www; 
            else return  inf; 
} 
int main()  
{  
    int x,y,z; 
    cin>>n>>m;  
    all=(1<<n)-1; 
    for(int i=1;i<=n;i++)  
    {  
        cin>>a[i];  
    }  
     for(int i=1;i<=m;i++) 
    { 
            scanf("%d%d%d",&x,&y,&z); 
            x++,y++;
            e[++cnt].st=x; 
            e[cnt].en=y; 
            e[cnt].w=z; 
    } 
    for(int i=0;i<=all;i++) sum[i]=inf,dp[i]=inf; 
     sort(e+1,e+1+cnt,cmp); 
     for(int i=0;i<=all;i++) 
     { 
         int sumM=0,tot=0; 
                for(int j=1;j<=n;j++)
                if((1<<j-1)&i)
                { 
                
                    sumM+=a[j]; 
                    tot++; 
                } 
                if(sumM==0&&tot) 
                { 
                    dp[i]=krus(i,tot); 
                    sum[i]=0; 
                } 
     } 
     for(int i=0;i<=all;i++) 
     { 
         if(sum[i]==0) 
         { 
             for(int j=0;j<=all;j++) 
             { 
                 if(sum[j]==0) 
                 { 
                     dp[i|j]=min(dp[i|j],dp[i]+dp[j]); 
                 } 
             } 
         } 
     } 
     if(dp[all]!=inf)
     cout<<dp[all]; 
     else
     cout<<"Impossible";
      
}

Guess you like

Origin www.cnblogs.com/OIEREDSION/p/11432775.html