https://www.luogu.com.cn/problem/P3264
就跑跑斯坦纳树,然后由于只需要相同的组在一起就行,那么最后还需要合并一下,也就是g[s]=min(g[s],g[t]+g[s^t])其中t和s^t对于每一组来说要么全在里面,要么全不在里面
#include<bits/stdc++.h>
using namespace std;
const int maxl=1e3+10;
int n,m,p,up,inf,ans;
int a[maxl],dy[maxl],msk[maxl];
int f[1<<10][maxl],g[1<<10];
struct ed{int to,l;};
vector<ed> e[maxl];
vector<int> b[11];
bool in[maxl];
queue<int> q;
inline void prework()
{
scanf("%d%d%d",&n,&m,&p);
int u,v,w;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w);
e[u].push_back(ed{v,w});
e[v].push_back(ed{u,w});
}
for(int i=1;i<=p;i++)
{
scanf("%d%d",&u,&v);
b[u].push_back(i);
a[i]=v;dy[v]=i;msk[u]|=1<<(i-1);
}
}
inline bool ck(int s)
{
int len;
for(int i=1;i<=10;i++)
if((msk[i]&s)!=0 && (msk[i]&s)!=msk[i])
return false;
return true;
}
inline void spfa(int f[])
{
int u,v;
while(!q.empty())
{
u=q.front();q.pop();
for(ed ee:e[u])
{
v=ee.to;
if(f[v]<=f[u]+ee.l)
continue;
f[v]=f[u]+ee.l;
if(!in[v])
{
q.push(v);
in[v]=true;
}
}
in[u]=false;
}
}
inline void mainwork()
{
memset(f,0x3f,sizeof(f));
memset(g,0x3f,sizeof(g));
up=1<<p;inf=f[0][0];
for(int i=1;i<=p;i++)
f[1<<(i-1)][a[i]]=0;
for(int s=0;s<up;s++)
{
for(int i=1;i<=n;i++)
{
for(int t=s&(s-1);t;t=(t-1)&s)
f[s][i]=min(f[s][i],f[t][i]+f[s^t][i]);
if(f[s][i]<inf)
q.push(i),in[i]=true;
}
spfa(f[s]);
for(int i=1;i<=n;i++)
g[s]=min(g[s],f[s][i]);
}
for(int s=0;s<up;s++)
for(int t=s&(s-1);t;t=(t-1)&s)
if(ck(t) && ck(s^t))
g[s]=min(g[s],g[s^t]+g[t]);
ans=g[up-1];
}
inline void print()
{
printf("%d\n",ans);
}
int main()
{
prework();
mainwork();
print();
return 0;
}