1.
1349:【例4-10】最优布线问题
时间限制: 1000 ms 内存限制: 65536 KB
提交数: 6893 通过数: 4250
【题目描述】
学校有nn台计算机,为了方便数据传输,现要将它们用数据线连接起来。两台计算机被连接是指它们有数据线连接。由于计算机所处的位置不同,因此不同的两台计算机的连接费用往往是不同的。
当然,如果将任意两台计算机都用数据线连接,费用将是相当庞大的。为了节省费用,我们采用数据的间接传输手段,即一台计算机可以间接的通过若干台计算机(作为中转)来实现与另一台计算机的连接。
现在由你负责连接这些计算机,任务是使任意两台计算机都连通(不管是直接的或间接的)。
【输入】
第一行为整数nn(2≤n≤1002≤n≤100),表示计算机的数目。此后的nn行,每行nn个整数。第x+1x+1行yy列的整数表示直接连接第xx台计算机和第yy台计算机的费用。
【输出】
一个整数,表示最小的连接费用。
【输入样例】
3
0 1 2
1 0 1
2 1 0
【输出样例】
2
【提示】
注:表示连接1和2,2和3,费用为2。
####
解:题目为最小生成树的模板,只需要把最小生成树给求出,然后把个边加一起就可以算出最小花费。为了方便可以把最小生成树模板给改一下,设置一个cnt记录当前加入了几条边,当为n-1时结束,因为第一条为1-1所以不加,其它均result+=nd.w,最后result就是正确结果。
代码
#include<bits/stdc++.h>
using namespace std;
const int mxv=0x3f3f3f3f;
const int mxn=100;
struct node{
int from,id,w;
node(){
}
node(int arfrom,int arid,int arw){
from=arfrom;
id=arid;
w=arw;
}
friend bool operator < (node a,node b){
return a.w>b.w;
}
};
int n,e,g[mxn+9][mxn+9],n1,n2,w;
bool flag[mxn+9];
int cnt;
priority_queue<node>pque;
int prim(int sid){
int result=0;
memset(flag,false,sizeof(flag));
pque.push(node(-1,sid,0));
while(cnt<n){
node nd=pque.top();pque.pop();
if(flag[nd.id])continue;
flag[nd.id]=true;
cnt++;
if(cnt!=1)result+=nd.w;
for(int i=1;i<=n;i++){
if(!flag[i]&&g[nd.id][i]<mxv){
pque.push(node(nd.id,i,g[nd.id][i]));
}
}
}
return result;
}
int main(){
memset(g,0x3f,sizeof(g));
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>e;
g[i][j]=g[j][i]=e;
}
}
//i=1;
cout<<prim(1);
return 0;
}
2.
1391:局域网(net)
时间限制: 1000 ms 内存限制: 65536 KB
提交数: 5574 通过数: 3460
【题目描述】
某个局域网内有n(n≤100)n(n≤100)台计算机,由于搭建局域网时工作人员的疏忽,现在局域网内的连接形成了回路,我们知道如果局域网形成回路那么数据将不停的在回路内传输,造成网络卡的现象。因为连接计算机的网线本身不同,所以有一些连线不是很畅通,我们用f(i,j)f(i,j)表示i,ji,j之间连接的畅通程度(f(i,j)≤1000)(f(i,j)≤1000),f(i,j)f(i,j)值越小表示i,ji,j之间连接越通畅,f(i,j)f(i,j)为00表示i,ji,j之间无网线连接。现在我们需要解决回路问题,我们将除去一些连线,使得网络中没有回路,并且被除去网线的Σf(i,j)Σf(i,j)最大,请求出这个最大值。
【输入】
第一行两个正整数n,kn,k
接下来的kk行每行三个正整数i,j,mi,j,m表示i,ji,j两台计算机之间有网线联通,通畅程度为mm。
【输出】
一个正整数,Σf(i,j)Σf(i,j)的最大值。
【输入样例】
5 5
1 2 8
1 3 1
1 5 3
2 4 5
3 4 2
【输出样例】
8
分析题目总边长等于花费的加除去的,只需要让花费的最少那除去的就会最多,所以只需要求出最短生成树之后用总边长减去最小生成树,就是最多剩下的,所以这个题与1349基本一样,求出最小生成树花费;然后用总边长减去花费就是最大除去;
代码
#include<bits/stdc++.h>
using namespace std;
const int mxv=0x3f3f3f3f;
const int mxn=100;
struct node{
int from,id,w;
node(){
}
node(int arfrom,int arid,int arw){
from=arfrom;
id=arid;
w=arw;
}
friend bool operator < (node a,node b){
return a.w>b.w;
}
};
int n,e,g[mxn+9][mxn+9],n1,n2,w,zs;
bool flag[mxn+9];
int cnt;
priority_queue<node>pque;
int prim(int sid){
int result=0;
memset(flag,false,sizeof(flag));
pque.push(node(-1,sid,0));
while(cnt<n){
node nd=pque.top();pque.pop();
if(flag[nd.id])continue;
flag[nd.id]=true;
cnt++;
if(cnt!=1)result+=nd.w;
for(int i=1;i<=n;i++){
if(!flag[i]&&g[nd.id][i]<mxv){
pque.push(node(nd.id,i,g[nd.id][i]));
}
}
}
return result;
}
int main(){
memset(g,0x3f,sizeof(g));
cin>>n>>e;
for(int i=1;i<=e;i++){
cin>>n1>>n2>>w;
g[n1][n2]=w;
g[n2][n1]=w;
zs+=w;
}
//i=1;
cout<<zs-prim(1);
return 0;
}