【最小生成树变形】HDU 3367
题意:求最大的边权值的和
满足在一个连通图里最多有一个环
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
#include <queue>
#include <stack>
#include <vector>
#include <deque>
#include <set>
#include <map>
#define IN freopen ("in.txt" , "r" , stdin);
#define OUT freopen ("out.txt" , "w" , stdout);
typedef long long LL;
const int MAXN = 11111;//点数的最大值
const int MAXM = 111111;//边数的最大值
const LL INF = 1152921504;
int fa[MAXN],flag[MAXN];
struct node
{
int u,v;
LL cost;
}edge[MAXM];
bool cmp(node a,node b)
{
return a.cost>b.cost;
}
void init()
{
for(int i=0;i<MAXN;i++)
fa[i]=i,flag[i]=0;
}
int find(int x)
{
if(x==fa[x])
return x;
else
{
fa[x]=find(fa[x]);
return fa[x];
}
}
LL kruskal(int m)//flag 表示该点所在的连通图有无环
{
init();
LL res=0;
for(int i=0;i<m;i++)
{
node e=edge[i];
int fu=find(e.u),fv=find(e.v);
if(fu!=fv)//在不同的连通图里
{
if(!flag[fu]&&!flag[fv])//两个连通图都没有环
res+=e.cost,fa[fu]=fv;
else if(!flag[fu])//其中一个有环
{
res+=e.cost;
flag[fu]=1;
fa[fv]=fu;
}
else if(!flag[fv])
{
res+=e.cost;
flag[fv]=1;
fa[fu]=fv;
}
}
else if(!flag[fu])//在一个连通图里,且无环
{
res+=e.cost;
flag[fu]=1;
}
}
return res;
}
int main()
{
int n,m;
// IN;
while(scanf("%d%d",&n,&m),n+m)
{
for(int i=0;i<m;i++)
scanf("%d%d%I64d",&edge[i].u,&edge[i].v,&edge[i].cost);
sort(edge,edge+m,cmp);
printf("%I64d\n",kruskal(m));
}
}

浙公网安备 33010602011771号