1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <queue> #define ll long long using namespace std; template <class T> inline void rd(T &x) { x=0; char c=getchar(); int f=1; while(!isdigit(c)) { if(c=='-') f=-1; c=getchar(); } while(isdigit(c)) x=x*10-'0'+c,c=getchar(); x*=f; } const int N=55; int d[N][N],n,m,K; int f[N][1<<10],g[1<<10],vid[N]; queue<int> que; int vis[N]; void spfa(int c) { while(!que.empty()) { int u=que.front(); que.pop(),vis[u]=0; for(int v=1;v<=n;++v) if(f[v][c]>f[u][c]+d[u][v]) { f[v][c]=f[u][c]+d[u][v]; if(!vis[v]) que.push(v),vis[v]=1; } } } int main() { int T; rd(T); while(T--) { rd(n),rd(m),rd(K); memset(d,0x3f,sizeof(d)); for(int x,y,w,i=1;i<=m;++i) { rd(x),rd(y),rd(w); d[x][y]=min(d[x][y],w); d[y][x]=min(d[y][x],w); } memset(vid,0,sizeof(vid)); for(int i=1;i<=K;++i) vid[i]=i; for(int i=n-K+1;i<=n;++i) vid[i]=K+(n-i+1); memset(f,0x3f,sizeof(f)); for(int i=1;i<=n;++i) { if(vid[i]) f[i][1<<vid[i]-1]=0; f[i][0]=0; } for(int s=1;s<(1<<(K*2));++s) { for(int i=1;i<=n;++i) for(int t=s&(s-1);t;t=(t-1)&s) f[i][s]=min(f[i][s],f[i][t]+f[i][s^t]); for(int i=1;i<=n;++i) if(f[i][s]<1e7) que.push(i),vis[i]=1; spfa(s); } memset(g,0x3f,sizeof(g)); for(int s=1;s<(1<<(K*2));++s) { int cnt1=0,cnt2=0; for(int i=1;i<=K;++i) if(s&(1<<i-1)) cnt1++; for(int i=K+1;i<=2*K;++i) if(s&(1<<i-1)) cnt2++; if(cnt1!=cnt2) continue; for(int i=1;i<=n;++i) g[s]=min(g[s],f[i][s]); } for(int s=0;s<(1<<(2*K));++s) for(int t=s&(s-1);t;t=(t-1)&s) g[s]=min(g[s],g[t]+g[s^t]); int ans=g[(1<<(2*K))-1]; if(ans>1e7) printf("No solution\n"); else printf("%d\n",ans); } return 0; }
|