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";
}