度度熊国王率领着喵哈哈族的勇士,准备进攻哗啦啦族。
哗啦啦族是一个强悍的民族,里面有充满智慧的谋士,拥有无穷力量的战士。
所以这一场战争,将会十分艰难。
为了更好的进攻哗啦啦族,度度熊决定首先应该从内部瓦解哗啦啦族。
第一步就是应该使得哗啦啦族内部不能同心齐力,需要内部有间隙。
哗啦啦族一共有n个将领,他们一共有m个强关系,摧毁每一个强关系都需要一定的代价。
现在度度熊命令你需要摧毁一些强关系,使得内部的将领,不能通过这些强关系,连成一个完整的连通块,以保证战争的顺利进行。
请问最少应该付出多少的代价。
Input
本题包含若干组测试数据。
第一行两个整数n,m,表示有n个将领,m个关系。
接下来m行,每行三个整数u,v,w。表示u将领和v将领之间存在一个强关系,摧毁这个强关系需要代价w
数据范围:
2<=n<=3000
1<=m<=100000
1<=u,v<=n
1<=w<=1000
Output
对于每组测试数据,输出最小需要的代价。
Sample Input
2 1 1 2 1 3 3 1 2 5 1 2 4 2 3 3
Sample Output
1 3
题意:给你一个连通图,你可以去掉一些连通分量,使它变成非连通图,求最小的去掉的连通分量
思路:
先判断所给的图是否为来连通图,如果不是则输出0,图内一共有N个点,那么根据并查集的性质,会有N-1个点并入到某一个点为根节点的集合中去,所以设Cnt=N-1,每次合并的时候Cnt--;
Sum[i]数组存储每个点的连通值,即每个点与其他点连接时的权值的和(千万要记住自己与自己连接的权值不要加和)
代码:
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=3005;
#define inf 0x3f3f3f3f
int pre[maxn];
int sum[maxn];
int n,m;
int find(int x)
{
if(pre[x]==x)
return x;
return pre[x]=find(pre[x]);
}
bool merge(int x,int y)
{
int fx=find(x);
int fy=find(y);
if(fx!=fy)
{
pre[fx]=fy;
return true;
}
return false;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
int cnt=n-1;
memset(sum,0,sizeof(sum));
for(int i=0;i<maxn;i++)
pre[i]=i;
int u,v,w;
while(m--)
{
scanf("%d%d%d",&u,&v,&w);
if(u==v) continue;//*同一个点的权值不需要加和
sum[u]+=w;
sum[v]+=w;
if(merge(u,v)) cnt--;//如果没有建立关系,合并,已建立关系, 不需要合并
}
if(cnt!=0) cout<<"0"<<endl;
else
{
int minn=inf;
for(int i=1;i<=n;i++)
if(minn>sum[i])
minn=sum[i];
cout<<minn<<endl;
}
}
return 0;
}