【复习】---【p2820】局域网--洛谷//最小生成树 (2)
题目背景
某个局域网内有n(n<=100)台计算机,由于搭建局域网时工作人员的疏忽,现在局域网内的连接形成了回路,我们知道如果局域网形成回路那么数据将不停的在回路内传输,造成网络卡的现象。因为连接计算机的网线本身不同,所以有一些连线不是很畅通,我们用f(i,j)表示i,j之间连接的畅通程度,f(i,j)值越小表示i,j之间连接越通畅,f(i,j)为0表示i,j之间无网线连接。
题目描述
需要解决回路问题,我们将除去一些连线,使得网络中没有回路,并且被除去网线的Σf(i,j)最大,请求出这个最大值。
输入输出格式
输入格式:
第一行两个正整数n k
接下来的k行每行三个正整数i j m表示i,j两台计算机之间有网线联通,通畅程度为m。
输出格式:
一个正整数,Σf(i,j)的最大值
输入输出样例
输入样例#1:
5 5
1 2 8
1 3 1
1 5 3
2 4 5
3 4 2
输出样例#1:
8
思路:既然要求出拆去一些边的最大权值,那我们就可以想到我们只要是连着的边无回路权值和最小即可.....说到这你想到了什么??
(╯‵□′)╯︵┻━┻最小生成树!!
对,我们只需要求出最小生成树记录下最小生成路的总权值,然后用最初的总权值-最小生成树权值=ANS!
代码如下:
我用的Kruskal。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #define MAXN 101000 7 using namespace std; 8 inline int read() 9 { 10 int x=0,f=1; 11 char ch=getchar(); 12 while(ch>'9'||ch<'0') 13 { 14 if(ch=='-') 15 f=-1; 16 ch=getchar(); 17 } 18 while(ch>='0'&&ch<='9') 19 { 20 x=x*10+ch-'0'; 21 ch=getchar(); 22 } 23 return x*f; 24 } 25 struct drt 26 { 27 int x,y,v; 28 }a[MAXN]; 29 int f[MAXN]; 30 bool mycmp(drt x,drt y) 31 {return x.v<y.v;} 32 int getfather(int k) 33 { 34 if(f[k]==k) 35 return k; 36 f[k]=getfather(f[k]); 37 return f[k]; 38 } 39 int main() 40 { 41 int n=read(),k=read(); 42 int sum0=0; 43 for(int i=1;i<=k;i++) 44 { 45 a[i].x=read(); 46 a[i].y=read(); 47 a[i].v=read(); 48 sum0+=a[i].v; 49 } 50 for(int i=1;i<=n;i++) 51 f[i]=i; 52 sort(a+1,a+1+k,mycmp); 53 int cal=0; 54 int sum1=0; 55 for(int i=1;i<=k;i++) 56 { 57 int v=getfather(a[i].x); 58 int u=getfather(a[i].y); 59 if(v!=u) 60 { 61 f[v]=u; 62 sum1+=a[i].v; 63 if(++cal==n-1) 64 break; 65 } 66 } 67 cout<<sum0-sum1<<endl; 68 return 0; 69 }