#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxm=11e2+9,maxn=10e1+9;
int dp[maxm][maxn],num[maxn],d[maxn][maxn];
int n,m,k;
bool visit[maxn],chk[maxm];
void getdp()
{
memset(dp,50,sizeof(dp));
memset(num,0,sizeof(num));
for(int i=1;i<=k;i++)
{
num[i]=1<<i-1;
num[n-k+i]=1<<i+k-1;
}
// for(int j=1;j<=n;j++)
for(int i=1;i<=n;i++)
{
// dp[num[i]|num[j]][j]=min(dp[num[i]|num[j]][j],d[i][j]);
dp[num[i]][i]=0;
dp[0][i]=0;
}
for(int p=0;p<(1<<k+k);p++)
{
// cout<<p<<endl;
for(int q=1;q<=n;q++)
{
for(int i=p;i;i=i-1&p)
dp[p][q]=min(dp[p][q],dp[i][q]+dp[p^i][q]);
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
dp[p][i]=min(dp[p][i],dp[p][j]+d[j][i]);
}
}
void getans()
{
for(int p=0;p<(1<<k+k);p++)
for(int i=1;i<=n;i++)
dp[p][0]=min(dp[p][0],dp[p][i]);
for(int i=0;i<(1<<k+k);i++)
if(chk[i])
for(int j=i;j;j=j-1&i)
if(chk[j])
{
dp[i][0]=min(dp[i][0],dp[i^j][0]+dp[j][0]);
}
}
void getchk()
{
for(int i=0;i<(1<<k+k);i++)
{
int tmp=0,txt=0;
for(int j=1;j<=k;j++)
if(i&(1<<j-1)) tmp++;
for(int j=k+1;j<=k+k;j++)
if(i&(1<<j-1)) txt++;
if(tmp==txt)
chk[i]=1;
else chk[i]=0;
}
}
void floyed()
{
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
}
void solve()
{
floyed();
getdp();
getchk();
getans();
if(dp[(1<<k+k)-1][0]<1e8)
cout<<dp[(1<<k+k)-1][0]<<endl;
else
printf("No solution\n");
}
int main()
{
// freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
memset(d,50,sizeof(d));
scanf("%d%d%d",&n,&m,&k);
for(int i=1,from,to,w;i<=m;i++)
{
scanf("%d%d%d",&from,&to,&w);
// d[from][to]=w;
d[from][to]=min(w,d[from][to]);
d[to][from]=d[from][to];
}
solve();
}
return 0;
}
hdu 4085 斯坦纳树
最新推荐文章于 2019-07-26 15:04:46 发布