http://poj.org/problem?id=2377
题意:约翰雇Bessie来在自己的仓库之间设计一个通路网络,约翰已经找出仓库之间修路的成本,要求做一个最小成本的通路网络。但是这货居然不想给钱,Bessie就看这智障不爽了,反正不给钱,索性给你设计个成本最大的网络,忙活去吧= =,求最大网络的成本。
思路:最大生成树。这题n的数量不是很大,所以用两种做法都做了一下。Prim的话把所有的最小改成最大就好,Kruskal只要把边的顺序改成从大到小就行。这题有个坑,不连通要输出-1,被坑了几次= =。。。
#include <stdio.h>
#include <algorithm>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <queue>
using namespace std;
typedef long long LL;
const int N = 1005;
const int INF = 0x3f3f3f3f;
int maxcost[N], G[N][N], pre[N], n, ednum, sum;
bool vis[N];
struct node
{
int u, v, w;
}edge[20005];
bool cmp(node x, node y)
{
if(x.w>y.w) return true;
else return false;
}
bool prim()
{
for(int i = 1; i <= n; i++)
{
maxcost[i] = G[1][i];//从起点到各个点的花费
}
memset(vis, false, sizeof(vis));
vis[1] = true;
for(int i = 2; i <= n; i++)//起点已访问过。遍历n-1个节点
{
int k = -1, maxpath = -INF;
for(int j = 1; j <= n; j++)
{
if(!vis[j] && (k==-1 || maxcost[j]>maxpath))//寻找起点离未访问节点花费最大的点
{
k = j;
maxpath = maxcost[j];
}
}
if(k == -1) break;//已经遍历所有的点
if(maxpath == -INF) return false;//找完花费最大的点后还是非法花费,则发现不连通的点
vis[k] = true;
sum+=maxpath;
for(int j = 1; j <= n; j++)//以上面找出花费最大的节点为起点更新其对其他未访问节点的最大花费
{
if(!vis[j]) maxcost[j] = max(maxcost[j], G[k][j]);
}
}
return true;
}
int Find(int x)
{
int r = x;
while(r != pre[r])
r = pre[r];
int i = x, j;
while(pre[i] != r)
{
j = pre[i];
pre[i] = r;
i = j;
}
return r;
}
void Union(int p1, int p2, int w)
{
int x = Find(p1);
int y = Find(p2);
if(x != y)
{
pre[x] = y;
sum+=w;
}
}
bool kruskal()
{
for(int i = 1; i <= n; i++)
pre[i] = i;
sort(edge+1, edge+1+ednum, cmp);
for(int i = 1; i <= ednum; i++)
{
Union(edge[i].u, edge[i].v, edge[i].w);
}
int cnt = 0;
for(int i = 1; i <= n; i++)
{
if(pre[i] == i) cnt++;
}
if(cnt > 1) return false;
else return true;
}
int main()
{
// freopen("in.txt", "r", stdin);
int u, v, w;
while(~scanf("%d%d", &n, &ednum))
{
sum = 0;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
{
if(i == j) G[i][j] = 0;
else G[i][j] = -INF;
}
for(int i = 1; i <= ednum; i++)
{
scanf("%d%d%d", &u, &v, &w);
if(w>G[u][v]) G[u][v] = G[v][u] = w;
edge[i] = (struct node){u, v, w};
}
/* if(prim()) printf("%d\n", sum);
else printf("-1\n");*/
if(kruskal()) printf("%d\n", sum);
else printf("-1\n");
}
return 0;
}