prim 建构最小生成树
/*
O(n^2)时间复杂度
稠密图 用 g 邻接矩阵
思路 :
本质在边不在点 因为是无向图 所以一对点谁先放到树中无所谓
每次枚举一下 没在树上的点到树上点的最短边(根据贪心 因为是无向图所以它到所有
它能到的点,和这些能到的点到它的距离相同 所有 最优方案自然是把当前最短边放进去
再用这个点到其他点的距离更新其他点(这些剩下的点的距离会被更新到更小))
然后把这个点放在树里面 在用这个点
更新所有没在树上的点的到树最短距离
*/
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 555;
typedef pair<int, int> PII;
int dist[N];
int g[N][N];
bool st[N];
int n,m;
int prim()
{
int res=0;
memset(dist, 0x3f, sizeof dist);
int t=0;
dist[1]=0;
while(t!=-1)
{
t=-1;
for(int i=1;i<=n;i++)
{
if(!st[i]&&(t==-1||dist[t]>dist[i]))
{
t=i;
}
}
st[t]=1;
if(dist[t]==0x3f3f3f3f&&t!=-1&&t!=1)
{
return dist[t];
}
if(t!=1)res+=dist[t];
for(int i=1;i<=n;i++) dist[i]=min(dist[i],g[t][i]);
}
return res;
}
int main()
{
cin>>n>>m;
memset(g, 0x3f, sizeof g);
while (m -- )
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
g[x][y]=g[y][x]=min(g[x][y],z);
}
int dmin=prim();
if(dmin==0x3f3f3f3f) puts("impossible");
else cout<<dmin<<endl;
}