马上码长都有正常搜索2倍了
求助
此代码怪异的几点:
跑kruskal求理论最小代价(???)
排序后加边会 70→65
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
struct Edge{
int to;
int next;
int w;
}edge[2001];
struct z{
int u,v,w;
};
int cnt=1,head[13];
int n,m,tot;
int ans=12*5*100000+5;
bool flag[13];
int dist[13];
void add(int u,int v,int w){
edge[cnt].to=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt++;
}
vector<int> way;
vector<z> W;
void dfs(int cnt,int p,int d){
if(p>ans) return ;
if(cnt==n){ans=min(ans,p);return ;}
for(int itt=0;itt<way.size();++itt){
int it=way[itt];
if(p+d*dist[it]>=ans) return ;
for(int i=head[it];i!=0;i=edge[i].next){
int f=edge[i].to;
if(!flag[f]){
flag[f]=1;
dist[f]=dist[it]+1;
way.push_back(f);
dfs(cnt+1,p+edge[i].w*dist[it],d-edge[i].w);
way.pop_back();
flag[f]=0;
dist[f]=0;
}
}
}
}
bool cmp(z a,z b){
return a.w<b.w;
}
int fa[15];
int find(int x){
return fa[x]==x?x:fa[x]=find(fa[x]);
}
void merge(int x,int y){
fa[find(x)]=find(y);
}
void kruskal(){
int limit=n-1;
sort(W.begin(),W.end(),cmp);
for(int i=0;i<W.size();++i){
if(find(W[i].u)!=find(W[i].v)){
tot+=W[i].w;
limit--;
merge(W[i].u,W[i].v);
if(limit==0) return ;
}
}
}
char buf[1<<23],*p1=buf,*p2=buf,obuf[1<<23],*O=obuf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
inline int rd() {
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return x*f;
}
int main(){
n=rd(),m=rd();
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=1;i<=m;++i){
int u,v,w;
u=rd(),v=rd(),w=rd();
// add(u,v,w);
// add(v,u,w);
W.push_back((z){u,v,w});
W.push_back((z){v,u,w});
}
kruskal();
for(int i=0;i<W.size();++i){
add(W[i].u,W[i].v,W[i].w);
}
for(int i=1;i<=n;i++){
way.clear();
flag[i]=1;
dist[i]=1;
way.push_back(i);
dfs(1,0,tot);
flag[i]=0;
}
cout<<ans;
}