cowtract(网络)
题目描述:
Bessie受雇来到John的农场帮他们建立internet网络。农场有N (2<= N <= 1,000)牛棚,编号为1..N。John之前已经勘测过,发现有 M (1<= M <= 20,000)条可能的连接线路,一条线路是连接某两个牛棚的。每条可能的线路都有一个建设费用 C (1<= C <=100,000)。John当然想花尽量少的钱,甚至克扣Bessie的工钱。
Bessie发现了这点,很生气,决定给John捣乱。她要选择一些线路组成网,但费用却尽可能大。当然网络要能正常工作,也就是任意两个牛棚之间都是相互可以连通的,并且网络上不能有环,不然John会很容易发现的。
请计算组建这种网络最多可能的费用。
输入文件 cowtract.in
第一行:两个整数 N M
下面M行:每行3个整数 A,B,C。表示一个可能的线路要连接A、B两个牛棚,费用是C。
输出文件 cowtract.out
只一行,一个整数,即花费最大的费用。如果不可能连接通所有牛棚,输出-1。
样例
输入 | 5 8 | 17 + 8 + 10 + 7 = 42 |
输出 | 42 |
|
方法:甩队列,不断维护,更新,prim。
<pre name="code" class="csharp"><pre name="code" class="cpp">#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>//队列 神器
using namespace std;
const int N=1001;
queue<int> q;
int n,m;
bool used[N],conect[N];
long long ans;
int cost[N][N],most[N],close[N];
bool bfs()
{
int i,now=1,head;
while(!q.empty())
q.pop();
q.push(1);
conect[1]=1;
while (!q.empty())
{
head=q.front();
for (i=1;i<=n;i++)
if (cost[head][i]!=0)
if (!conect[i])
{
q.push(i);
conect[i]=1;
now++;
}
q.pop();
}
if (now==n)
return 1;
return 0;
}
void build_tree()
{
int i,mymin,j,now;
for (i=1;i<n;i++)
{
mymin=0;
for (j=1;j<=n;j++)
if (most[j]>mymin)
if (!used[j])
{
mymin=most[j];
now=j;
}
used[now]=1;
for (j=1;j<=n;j++)
if (!used[j])
if (cost[j][now]>most[j])
{
most[j]=cost[j][now];
close[j]=now;
}
}
return;
}
void fuckworking()
{
int i;
if (!bfs())
{
printf("-1");
return;
}
else
{
build_tree();
for (i=2;i<=n;i++)
ans+=cost[i][close[i]];
printf("%d",ans);
}
return;
}
int main()
{
freopen("cowtract.in","r",stdin);
freopen("cowtract.out","w",stdout);
int a,b,c,i;
scanf("%d %d",&n,&m);
for (i=1;i<=m;i++)
{
scanf("%d %d %d",&a,&b,&c);
cost[a][b]=max(cost[a][b],c);
cost[b][a]=cost[a][b];
}
used[1]=1;
for (i=1;i<=n;i++)
{
most[i]=cost[i][1];
close[i]=1;
}
fuckworking();
return 0;
}