斯坦纳森林 80分求助
查看原帖
斯坦纳森林 80分求助
394167
Cure_Wing楼主2024/7/22 16:04

9,10,17,19 错了。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
#include<queue>
using std::cin;using std::cout;
constexpr int N=1005,P=13,K=1027,inf=1e9;
int n,m,p,u,v,w,col[P],cnt,g[K],f[N][K],num;
struct A{int c,d;}a[P];
std::vector<A>edge[N];
std::queue<int>q;
bool vis[N];
signed main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	std::ios::sync_with_stdio(false);
	cin.tie(nullptr);cout.tie(nullptr);
	cin>>n>>m>>p;for(int i=1;i<=m;++i){cin>>u>>v>>w;edge[u].push_back(A{v,w});edge[v].push_back(A{u,w});}
	for(int i=1;i<=p;++i) cin>>a[i].c>>a[i].d;
	std::sort(a+1,a+p+1,[](A a,A b){return a.c<b.c;});
	for(int i=1;i<=p;++i){if(a[i].c!=a[i-1].c) ++cnt;col[i]=cnt;}
	for(int i=1;i<=p;++i) a[i].c=col[i];
	for(int i=1;i<(1<<cnt);++i){
		num=0;for(int j=1;j<=p;++j) if(i>>(a[j].c-1)&1) ++num;
		for(int j=1;j<=n;++j) for(int k=1;k<(1<<num);++k) f[j][k]=inf;
		for(int j=1;j<=p;++j) if(i>>(a[j].c-1)&1) f[a[j].d][1<<j-1]=0;
		for(int j=1;j<(1<<num);++j){
			for(int k=1;k<=n;++k){
				for(int l=(j-1)&j;l;l=(l-1)&j) f[k][j]=std::min(f[k][j],f[k][l]+f[k][j^l]);
				if(f[k][j]<inf){q.push(k);vis[k]=1;}
			}
			while(!q.empty()){
				int k=q.front();q.pop();vis[k]=0;
				for(A l:edge[k])
					if(f[k][j]+l.d<f[l.c][j]){
						f[l.c][j]=f[k][j]+l.d;
						if(!vis[l.c]){q.push(l.c);vis[l.c]=1;}
					}
			}
		}
		g[i]=inf;for(int j=1;j<=n;++j) g[i]=std::min(g[i],f[j][(1<<num)-1]);
	}
	for(int i=1;i<(1<<cnt);++i)
		for(int j=(i-1)&i;j;j=(j-1)&i)
			g[i]=std::min(g[i],g[j]+g[i^j]);
	cout<<g[(1<<cnt)-1];
	return 0;
}
2024/7/22 16:04
加载中...