题目大意:输入 m,n 表示路口,道路的数目,求出是所有路口畅通时政府所省的最大费用。
算法思想:
边输入便求和,计算出政府花费的总代价,然后用克鲁斯卡尔算法求出最小生成树,同时计算出最小代价,最后用总代价-最小代价,就OK了。
克鲁斯卡尔算法模板:
代码如下:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int MAXN=220000;
typedef struct {
int start;
int end;
int value;
} Edge;
Edge r[MAXN];
int node[MAXN];
bool cmp(Edge a,Edge b){
return a.value<b.value;
}
int Find_node(int n){
if(node[n]==-1) return n;
else
return node[n]=Find_node(node[n]);
}
bool Merge(int a,int b){
int r1=Find_node(a);
int r2=Find_node(b);
if(r1==r2)
return false;
else if(r1<r2)
node[r2]=r1;
else
node[r1]=r2;
return true;
}
int Dijkstra(int m,int n){
int ans=0,num=0;
for(int i=1;i<=n;i++){
if(Merge(r[i].start,r[i].end)){
ans+=r[i].value;
num++;
}
if(num==m-1) break;
}
if(num==m-1) return ans;
return -1;
}
int main(){
int m,n;
int x,y,z;
while(~scanf("%d%d",&m,&n)&&(m||n)){
int sum=0;
memset(node,-1,sizeof(node));
for(int i=1;i<=n;i++){
scanf("%d%d%d",&r[i].start,&r[i].end,&r[i].value);
sum+=r[i].value;
}
sort(r+1,r+1+n,cmp);
printf("%d\n",sum-Dijkstra(m,n));
}
return 0;
}