您的位置:首页 > 产品设计 > UI/UE

hdu 4126 Genghis Khan the Conqueror 最小生成树变形

2013-09-24 01:08 316 查看
先求最小生成树,然后dfs求生成树的最小替代边。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=3e3+9,inf=1e9;
int n,m;
int dist[maxn],g[maxn][maxn],tree[maxn][maxn];
int f[maxn][maxn];
struct
{
int head[maxn],lon;
struct
{
int next,to,w;
}e[maxn*maxn<<1];
void clear()
{
memset(head,-1,sizeof(head));
lon=0;
}
void add(int from,int to,int w=0)
{
e[++lon].to=to;
e[lon].w=w;
e[lon].next=head[from];
head[from]=lon;
}
}edge[2];

double prim()
{
int key[maxn],from[maxn];
bool visit[maxn];
memset(visit,0,sizeof(visit));
memset(key,50,sizeof(key));
memset(f,0,sizeof(f));
memset(tree,0,sizeof(tree));
visit[1]=1;
for(int k=edge[0].head[1];k!=-1;k=edge[0].e[k].next)
{
int u=edge[0].e[k].to;
key[u]=edge[0].e[k].w;
from[u]=1;
}
double ans=0;
for(int p=2,u;p<=n;p++)
{
int now=inf;
for(int i=1;i<=n;i++)
if(!visit[i]&&key[i]<now)
now=key[i],u=i;

edge[1].add(from[u],u);
edge[1].add(u,from[u]);
tree[from[u]][u]=tree[u][from[u]]=key[u];
for(int i=1;i<=n;i++)
if(visit[i])
f[u][i]=f[i][u]=max(f[u][i],key[u]);
ans+=key[u];
visit[u]=1;

for(int k=edge[0].head[u];k!=-1;k=edge[0].e[k].next)
{
int v=edge[0].e[k].to;
if(!visit[v]&&key[v]>edge[0].e[k].w)
{
from[v]=u;
key[v]=edge[0].e[k].w;
}
}
}
return ans;
}

int dfs(int now,int from)
{
int mmin=dist[now];
for(int k=edge[1].head[now];k!=-1;k=edge[1].e[k].next)
{
int u=edge[1].e[k].to;
if(u==from) continue;
mmin=min(dfs(u,now),mmin);
}
g[now][from]=g[from][now]=min(g[now][from],mmin);
return mmin;
}

int main()
{
while(scanf("%d %d",&n,&m),n||m)
{
edge[0].clear();
edge[1].clear();
for(int i=1,from,to,w;i<=m;i++)
{
scanf("%d %d %d",&from,&to,&w);
from++,to++;
edge[0].add(from,to,w);
edge[0].add(to,from,w);
}
double mst=prim();
memset(g,50,sizeof(g));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
dist[j]=inf;
for(int k=edge[0].head[i];k!=-1;k=edge[0].e[k].next)
{
int u=edge[0].e[k].to;
dist[u]=edge[0].e[k].w;
}
for(int k=edge[1].head[i];k!=-1;k=edge[1].e[k].next)
{
int u=edge[1].e[k].to;
dist[u]=inf;
}
dfs(i,0);
}

double ans=0;
int q;
scanf("%d",&q);
for(int i=1,from,to,w;i<=q;i++)
{
scanf("%d %d %d",&from,&to,&w);
from++,to++;

if(tree[from][to]==0)
{
//                ans+=mst;
int tmp=min(f[from][to],w);
ans+=mst+tmp-f[from][to];
}
else
{
int tmp=min(w,g[from][to]);
ans+=mst-tree[from][to]+tmp;
}
}
printf("%.4f\n",ans/q);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: