题目传送门:http://poj.org/problem?id=2377
Description
Bessie has been hired to build a cheap internet network among Farmer John’s N (2 <= N <= 1,000) barns that are conveniently numbered 1..N. FJ has already done some surveying, and found M (1 <= M <= 20,000) possible connection routes between pairs of barns. Each possible connection route has an associated cost C (1 <= C <= 100,000). Farmer John wants to spend the least amount on connecting the network; he doesn’t even want to pay Bessie.
Realizing Farmer John will not pay her, Bessie decides to do the worst job possible. She must decide on a set of connections to install so that (i) the total cost of these connections is as large as possible, (ii) all the barns are connected together (so that it is possible to reach any barn from any other barn via a path of installed connections), and (iii) so that there are no cycles among the connections (which Farmer John would easily be able to detect). Conditions (ii) and (iii) ensure that the final set of connections will look like a “tree”.
Input
Line 1: Two space-separated integers: N and M
Lines 2..M+1: Each line contains three space-separated integers A, B, and C that describe a connection route between barns A and B of cost C.
OutputLine 1: A single integer, containing the price of the most expensive tree connecting all the barns. If it is not possible to connect all the barns, output -1.
翻译:农夫约翰雇了Bessie来为他的n个牲棚连上网。每个牲棚的编号是从1-n的。约翰已经做好了调查,并且找出了M条在任意两个牲棚之间可能的网线连路。每一个连路都会消耗Ci块钱。约翰自己想用最少的钱完成这项工作。
可是,Bessie知道约翰不会付他工资(信誉问题?),所以他决定让约翰花最多的钱。他现在决定:
1.让每个牲棚都连上网。(让约翰以为他做好了工作)
2.让连路无法构成环。(环很容易被约翰检测到)
3.让约翰花最多的钱。
请求出约翰花的最多的钱是多少。
如果牲棚无法被全部连通,输出-1.
题解:
每个节点都要连通,不能构成环,最大权值和为多少。。。
很明显,这是一道生成树问题,就是稍微变换了一下,最小生成树变成了最大生成树。
以Kruskal算法为例,只需要在根据边权排序时从升序变为降序即可。这样每次取出的边权为最大,满足Kruskal的原理。
最后,在判断连通时,只需遍历一次并查集,检查所有点是否属于同一个集合即可!
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define ll long long
using namespace std;
const ll N = 1005;
const ll M = N*N;
struct Edge
{
ll u,v,w;
}edge[M];
ll cc;
ll n,m;
ll ans=0;
ll fa[N];
bool cmp(Edge x,Edge y)
{
return (x.w>y.w);
}
ll getf(ll x)
{
if(fa[x]!=x)
fa[x]=getf(fa[x]);
return fa[x];
}
int main()
{
ll i,j,k;
cin>>n>>m;
for(i=1;i<=m;i++)
{
cc++;
ll a,b,c;
scanf("%lld%lld%lld",&a,&b,&edge[cc].w);
edge[cc].u=a;
edge[cc].v=b;
}
sort(edge+1,edge+cc+1,cmp);
for(i=1;i<=n;i++)
{
fa[i]=i;
}
for(i=1;i<=cc;i++)
{
ll a=getf(edge[i].u);
ll b=getf(edge[i].v);
if(a!=b)
{
fa[a]=b;
ans+=edge[i].w;
}
}
for(int i=1;i<n;i++)
{
if(getf(i)!=getf(i+1))
{
printf("-1");
return 0;
}
}
cout<<ans<<endl;
return 0;
}