您的位置:首页 > 其它

BOJ 474. 小妹妹送很多快递

2014-08-02 20:19 225 查看
题意:给出一张图,保证图是连通图。每条路上会有c个敌人。现在需要每个节点向其他的所有节点送信,只有信使的数量大于等于敌人的个数,才能通过该条路。信使会同时出发。问至少需要多少信使,才能完成上述任务。

思路:最小生成树。利用并查集维护图的连通。

并查集多维护的信息:1.连通块的个数,当整个图只有一个连通块时,退出图的构建。

2.该连通块中节点的个数。当两个块相连的时候,需要加上从一个块到另一个块信使的个数。

坑:即使路上没有敌人,仍然需要一个信使去送信。需要在连通块合并时特判。

代码如下:

#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

template<class T>
inline bool read(T &n){
T x = 0, tmp = 1; char c = getchar();
while ((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
if (c == EOF) return false;
if (c == '-') c = getchar(), tmp = -1;
while (c >= '0' && c <= '9') x *= 10, x += (c - '0'), c = getchar();
n = x*tmp;
return true;
}

template <class T>
inline void write(T n) {
if (n < 0) {
putchar('-');
n = -n;
}
int len = 0, data[20];
while (n) {
data[len++] = n % 10;
n /= 10;
}
if (!len) data[len++] = 0;
while (len--) putchar(data[len] + 48);
}

struct edge{
int u,v,cost;
bool operator < (const edge & a) const{
return cost < a.cost;
}
};

const int MAX = 101000;
int N,T,M;
edge G[MAX];
long long ans;

struct DisjointSet{
static const int MAX = 10010;
int father[MAX], rank[MAX],cnt,sum[MAX];
void clear(int n){
cnt = n;
memset(rank,0,sizeof(int) * (n + 1));
for(int i = 1; i <= n; ++i)
father[i] = i,sum[i] = 1;
}
int find(int x){
return x = x == father[x] ? x : find(father[x]);
}
void merge(edge e){
int x= e.u, y = e.v;
x = find(x),y = find(y);
if(x != y){
cnt--;

if(e.cost == 0)
ans += 2 * sum[x] * sum[y];
else
ans += 2 * sum[x] * sum[y] * e.cost;

if(rank[x] > rank[y]){
father[y] = x;
sum[x]  += sum[y];
}
else{
father[x] = y;
sum[y] += sum[x];
if(rank[x] == rank[y])
rank[y]++;
}
}
}
};

DisjointSet s;

int main(void)
{
read(T);
while(T--){
read(N),read(M);
s.clear(N);
ans = 0;
for(int i = 0 ; i < M; ++i)
read(G[i].u),read(G[i].v),read(G[i].cost);
sort(G,G + M);
for(int i = 0 ; i < M; ++i){
if(s.cnt == 1) break;
else if(s.find(G[i].u) != s.find(G[i].v)){
s.merge(G[i]);
}
}
printf("%lld\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: