此题和 hdu 3691 Nubulsa Expo 几乎一样
不再解释
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int INF=0x7fffffff;
const int N=505;
int a[N][N];
int dist[N];
bool visited[N],dele[N];
int n,m;
int nd1,nd2;
void Prim()
{
int st=1;
while(dele[st])
++st;
memset(dist,0,sizeof(dist));
for(int i=1;i<=n;++i)
{
if(!dele[i])
{
dist[i]=a[st][i];
}
}
nd1=nd2=st;
memset(visited,false,sizeof(visited));
visited[st]=true;
for(int w=1;w<n;++w)
{
int M=0,k=0;
for(int i=1;i<=n;++i)
{
if(!dele[i]&&!visited[i]&&dist[i]>M)
{
M=dist[i];k=i;
}
}
if(k==0)
break;
visited[k]=true;
for(int i=1;i<=n;++i)
{
if(!dele[i]&&!visited[i])
{
dist[i]+=a[k][i];//这里好奇怪
}
}
nd2=nd1;//最后更新点 和倒数第二更新点
nd1=k;
}
return;
}
int Findmin()
{
int sum=0;
for(int i=1;i<=n;++i)
{
if(!dele[i])
{
sum+=a[nd1][i];//最后更新点的割集
}
}
return sum;
}
void Removepoint()
{
dele[nd1]=true;
for(int i=1;i<=n;++i)
{
if(!dele[i]&&i!=nd2)
{
a[i][nd2]+=a[i][nd1];//合并最后更新点
a[nd2][i]+=a[nd1][i];
}
}
}
int main()
{
while(scanf("%d %d",&n,&m)!=EOF)
{
memset(a,0,sizeof(a));
while(m--)
{
int i,j,k;
scanf("%d %d %d",&i,&j,&k);
++i;++j;
a[i][j]+=k;//重边
a[j][i]+=k;
}
int ans=INF;
memset(dele,false,sizeof(dele));//此点是否删除
for(int w=1;w<n;++w)
{
Prim();
ans=min(ans,Findmin());
Removepoint();
}
printf("%d\n",ans);
}
return 0;
}
浙公网安备 33010602011771号